一》extjs的tree还是很强大的 可以支持拖放,全选,表格树等等。先看下效果图
对于tree来说,它的model是可以省略的,但是如果省略的话,就会引用一个隐式的model类型Ext.data.NodeInterface。一般情况下我们都使用默认的model类型。下面我们先声明一个treestore。
var store = new Ext.data.TreeStore({
proxy: {
type: 'ajax',
url: 'tree.shtml?id='+id
},
root: {
text: '根节点',
id: id,
expanded: true
}
});
然后我们再声明一个tree视图
var tree = new Ext.tree.TreePanel({
animate: true,
border: false,
rootVisible: false,
useArrows: true,
store: store,
height: 500,
width: 300,
listeners:{
"checkchange": function(node, state) {
node.checked = state;
if(!node.isLeaf()){
node.eachChild(function(childnode){
childnode.set('checked', state);
})
}
}
},
columns: [{
xtype: 'treecolumn',
text: '集电线/风机ID',
flex: 2,
sortable: true,
dataIndex: 'id'
},{
text: '集电线/风机名称',
flex: 2,
sortable: true,
dataIndex: 'text'
}]
});
这样我们就有了一个tree视图。
有了这些,我们再来看看怎么与后台交互数据,我使用的是spring3MVC,下面看我的controller的方法
//获取所有集电线信息列表树
@RequestMapping(value = "/tree", method = RequestMethod.GET)
@ResponseBody
public TreeNodeJson getClinesTree(int id) {
List clines = homeService.getCollLinesByFid(id);
if (clines != null && !clines.isEmpty()) {
TreeNodeJson root = new TreeNodeJson(farmid, null, false, false);
List ctreeChildren = new ArrayList();
for (CollLine cline : clines) {
TreeNodeJson cTreeNode = new TreeNodeJson(cline.getId(), cline.getName(), false, false);
List wts = homeService.getWtInfosByClid(cline.getId());
if (wts != null && !wts.isEmpty()) {
List wtreeChildren = new ArrayList();
for (WtInfo wt : wts) {
TreeNodeJson wTreeNode = new TreeNodeJson(wt.getWtid(), wt.getWtname(), true, false);
wtreeChildren.add(wTreeNode);
}
cTreeNode.setChildren(wtreeChildren);
}
ctreeChildren.add(cTreeNode);
}
root.setChildren(ctreeChildren);
return root;
} else {
return null;
}
}
对于TreeNodeJson 类,是我自己封装的一个树节点类型。这个类的结构有几个关键属性【children,leaf,checked,text】,有这几个属性后,当数据传到前台后,他就会匹配 Ext.data.NodeInterface的属性,来构建树结构。当然你还可以根据 Ext.data.NodeInterface的属性,完全构建一样的类结构,你还可以增加其他属性,但是几个关键属性石必须一致的。增加其他的属性石可以在表格的列属性里面引用的。
public class TreeNodeJson {
private int id;
private String text;
private String cls;
private List children;
private boolean leaf;
private boolean checked;
private String desp1;
private String desp2;
最后来说一下几个注意的地方:
1)节点全选的功能实现:
listeners:{
"checkchange": function(node, state) {
node.checked = state;
if(!node.isLeaf()){
node.eachChild(function(childnode){
childnode.set('checked', state);
})
}
}
},
这里面用到一个eachChild的遍历方法,然后使用set方法来设置是否全选,state是父节点的状态(是否被选),如果父节点被选择,那子节点全部被选,反之都不选。但是我这里只有一层,所以就没有迭代,如果是多层的树结构,是需要迭代的。
2)表格树结构:对于表格树结构很简单,直接加上columns就OK了,如果加上“treecolumn”,此列就会显示成树结构。
columns: [{
xtype: 'treecolumn',
text: '集电线/风机ID',
flex: 2,
sortable: true,
dataIndex: 'id'
},{
text: '集电线/风机名称',
flex: 2,
sortable: true,
dataIndex: 'text'
}]
3)后台树结构的构建:
TreeNodeJson root = new TreeNodeJson(farmid, null, false, false);
List ctreeChildren = new ArrayList();
for (CollLine cline : clines) {
TreeNodeJson cTreeNode = new TreeNodeJson(cline.getId(), cline.getName(), false, false);
List wts = homeService.getWtInfosByClid(cline.getId());
if (wts != null && !wts.isEmpty()) {
List wtreeChildren = new ArrayList();
for (WtInfo wt : wts) {
TreeNodeJson wTreeNode = new TreeNodeJson(wt.getWtid(), wt.getWtname(), true, false);
wtreeChildren.add(wTreeNode);
}
cTreeNode.setChildren(wtreeChildren);
}
ctreeChildren.add(cTreeNode);
}
root.setChildren(ctreeChildren);
return root;
首先构建一个根节点,然后加上孩子节点列表,然后再加上孩子的孩子节点列表。我这里只有两层结构,如果很多层的时候,最好使用迭代构建。