LazyTreeGrid的创建、菜单绑定和对菜单的限制
项目中需要用TreeGrid来显示比Tree更多的内容,因为TreeGrid相比Tree来说,不止是名字中多了一个Grid 那么简单,其实也差不多....
TreeGrid和Grid
TreeGrid可以算的上是Grid(多列字段显示)和Tree(强层级结构化)的组合,Grid是比较常用的组件,我们应用的时候,只需要提供layout(表格表头样式,根据指定的
field来显示store中data里面相应的字段值)和store(一般是用
dojo
.data.ItemFileWriteStore封装来的数据Object),通常给Grid指定了这两项主要参数即可。
由此,可以猜测,TreeGrid如何创建?
可参照DojoAPI-LazyTreeGrid: http://dojotoolkit.org/reference-guide/1.7/dojox/grid/LazyTreeGrid.html
在官方的Demo中,可以很清晰的看到,TreeGrid通过
dijit.tree.ForestStoreModel
来构造树的结构化数据,通过设置
childrenAttrs: ['children']就可以把数据中的父子筛选分开。
再模仿Grid,把layout设置一番,就可以了,可以根据业务需要进行设置,不一定每条数据(父或子)都有对应field的属性值,他们是一个集合关系。
如此,我们可以很清晰的看懂下面这段代码,无非就是TreeGrid较Tree有些方法不同的。
dojo.require("dojox.grid.LazyTreeGrid");dojo.require("dijit.tree.ForestStoreModel");dojo.require("dojo.data.ItemFileWriteStore");dojo.ready(function(){ /* set up data store */ var data = { identifier: 'name', label: 'name', items: [ { name:'Africa', type:'continent', children:[ { name:'Egypt', type:'country' }, { name:'Kenya', type:'country', children:[ { name:'Nairobi', type:'city', adults: 70400, popnum: 2940911 }, { name:'Mombasa', type:'city', adults: 294091, popnum: 707400 } ] }, { name:'Sudan', type:'country', children: { name:'Khartoum', type:'city', adults: 480293, popnum: 1200394 } } ] }, { name:'Asia', type:'continent', children:[ { name:'China', type:'country' }, { name:'India', type:'country' }, { name:'Russia', type:'country' }, { name:'Mongolia', type:'country' } ] }, { name:'Australia', type:'continent', population:'21 million', children: { name:'Commonwealth of Australia', type:'country', population:'21 million'} }, { name:'Europe', type:'continent', children:[ { name:'Germany', type:'country' }, { name:'France', type:'country' }, { name:'Spain', type:'country' }, { name:'Italy', type:'country' } ] }, { name:'North America', type:'continent', children:[ { name:'Mexico', type:'country', population:'108 million', area:'1,972,550 sq km', children:[ { name:'Mexico City', type:'city', adults: 120394, popnum: 19394839, population:'19 million', timezone:'-6 UTC'}, { name:'Guadalajara', type:'city', adults: 1934839, popnum: 4830293, population:'4 million', timezone:'-6 UTC' } ] }, { name:'Canada', type:'country', population:'33 million', area:'9,984,670 sq km', children:[ { name:'Ottawa', type:'city', adults: 230493, popnum: 9382019, population:'0.9 million', timezone:'-5 UTC'}, { name:'Toronto', type:'city', adults: 932019, popnum: 2530493, population:'2.5 million', timezone:'-5 UTC' }] }, { name:'United States of America', type:'country' } ] }, { name:'South America', type:'continent', children:[ { name:'Brazil', type:'country', population:'186 million' }, { name:'Argentina', type:'country', population:'40 million' } ] } ] }; var store = new dojo.data.ItemFileWriteStore({data: data}); var model = new dijit.tree.ForestStoreModel({store: store, childrenAttrs: ['children']}); /* set up layout */ var layout = [ {name: 'Name', field: 'name', width: '30%'}, {name: 'Type', field: 'type', width: '30%'}, {name: 'Population', field: 'population', width: '20%'}, {name: 'Area', field: 'area', width: '20%'} ]; /* create a new grid: */ var grid = new dojox.grid.LazyTreeGrid({ id: 'grid', treeModel: model, structure: layout, rowSelector: '20px' }, document.createElement('div')); /* append the new grid to the div */ dojo.byId("gridDiv").appendChild(grid.domNode); /* Call startup() to render the grid */ grid.startup();});
给TreeGrid设置菜单项:
这个问题,在网络上查询了一些资料,没有很适合的方法。然而,仔细想想,不放按照上面那番设想,我们菜单项无非就是绑定domNode即可,当然TreeGrid也提供了一些setMenu的方法,有setHeadMenu(但不合适),也看到有说setContextMenu的,但是没有成功。
this.treeGridMenu.set("targetNodeIds",[this.treeGrid.domNode]);
this.treeGridMenu.bindDomNode(this.treeGrid.domNode);
console.dir(["treeGrid",this.treeGrid]);
var aspect = dojo["require"]("dojo.aspect");
aspect.before(this.treeGridMenu, "_openMyself", dojo.hitch(this,this.clickItemBeforeOpenMenu));
后来,找到
onCellContextMenu方法,通过重写这个方法,不但使得Menu可以正常renderer出来,而且借此拿到了selectedItem。
this._treeGrid.onCellContextMenu = function(e){
this.selection.select(e.rowIndex);
cellNode = e.cellNode;
console.dir(["onCellContextMenu",e,
"getSelected",this.selection.getSelected()]);
};
LazyTreeGrid和TreeGrid,无什么大区别。
- LazyTreeGrid must have a TreeModel, the TreeModel could be the dijit.tree.ForestStoreModel/dojox.grid.LazyTreeGridStoreModel, or a custom TreeModel that inherited from them.
- LazyTreeGrid structures does not contain “children” values for nested level rows.(See dojox.grid.TreeGrid - Structure Definition)
- LazyTreeGrid does not contain an aggregate row, and its formatters don’t handle negative rowIndex values.
- LazyTreeGrid formatters receive a level parameter. (See “Formatting” below)
- defaultOpen/openAtLevels/aggregate/itemAggregates do not be available any more.
- The getItem function only accept a row index.