这个树,直接上代码吧
首先,UI上还是选择了放按钮而不是左键菜单
tbar: [
{
xtype: 'splitbutton',
text: '添加',
itemId: 'addnodebutton',
glyph: 0xf055,
//collapse:true,
menu:{
enableKeyNav: false,//开启/关闭在(网格内的)键盘导航。
items: [{
xtype: 'mynodeForm'
}]
}
},
{
text: '删除',
id:'deletenode',
glyph: 0xf146,
handler: function () {
var myTree = Ext.ComponentQuery.query('#stateTree')[0];
var addstore = myTree.getStore('treeStore');
var myTreesm = myTree.getSelectionModel();
if (myTreesm.hasSelection()) {
var mynode = myTreesm.getSelection()[0]
var nodedel = parseInt(mynode.data.id)
mynode.remove(true);
}
console.log(nodedel)
Ext.Ajax.request({
url: 'http://localhost:8899/api/department/TreelistDel',
method: 'GET',
params: { "ids": nodedel },
success: function (response) {
var text = response.responseText;
jsondata = Ext.util.JSON.decode(text)
}
});
}
},
{
xtype: 'splitbutton',
text: '编辑',
glyph: 0xf040,
itemId: 'alternodebutton',
menu:{
enableKeyNav: false,
items: [{
xtype: 'myalternodeForm'
}]
},
}]
左键菜单的实现如下
listeners:{
// 'itemcontextmenu': function (menutree, record, items, index, e) {
// e.preventDefault();
// e.stopEvent();
// //推断是否为叶子结点
// var nodemenu = new Ext.menu.Menu({
// floating: true,
// items: [{
// text: '添加',
// handler: function () {
// //for (var i = 0; i < record.data.children.length; ++i) {
// // //设置结点checked属性为true
// // record.childNodes[i].set('checked', true);
// //}
// var win = new Ext.Window({
// title: '处理状态',
// layout: 'fit',
// //modal: true,
// height: 137,
// width: 323,
// items: [{
// xtype: 'mynodeForm',
// }]
// })
// win.show();
// }
// }, {
// text: '编辑',
// handler: function () {
// for (var i = 0; i < record.data.children.length; ++i) {
// if (record.childNodes[i].data.checked == false) {
// //设置结点checked属性为true
// record.childNodes[i].set('checked', true)
// }
// else {
// //设置结点checked属性为true
// record.childNodes[i].set('checked', false);
// }
// }
// var win = new Ext.Window({
// title: '处理状态',
// layout: 'fit',
// //modal: true,
// height: 137,
// width: 323,
// items: [{
// xtype: 'myalternodeForm',
// }]
// })
// win.show();
// }
// }, {
// text: '删除',
// //handler:function(){
// // console.log('model')
// // var myTree = Ext.ComponentQuery.query('#stateTree')[0];
// // var addstore = myTree.getStore('treeStore');
// // console.log(Ext.getCmp('stateTree'))
// // console.log(Ext.getCmp('stateTree').getModel())
// //}
// handler: function () {
// //for (var i = 0; i < record.data.children.length; ++i) {
// // //设置结点checked属性为false
// // record.childNodes[i].set('checked', false);
// //}
// Ext.Msg.confirm('', '确定删除?', function (e) {
// if (e == 'yes') {
// var myTree = Ext.ComponentQuery.query('#stateTree')[0];
// var addstore = myTree.getStore('treeStore');
// console.log(addstore.getProxy().getModel('treemodel'))
// var myTreesm = myTree.getSelectionModel();
// if (myTreesm.hasSelection()) {
// //check if has selection
// var mynode = myTreesm.getSelection()[0];
// //get first selection item
// ids = parseInt(mynode.data.id)
// mynode.remove(true);
// addstore.getProxy().extraParams = {
// ids: parseInt(mynode.data.id),
// others: values.nodetext
// };
// addstore.destroy();
// // True (for destroy the node)
// }
// } else {
// this.close()
// }
// })
// //var myTree = Ext.ComponentQuery.query('#stateTree')[0];
// //var addstore = myTree.getStore('treeStore');
// //console.log(addstore.getProxy().getModel('treemodel'))
// // var myTreesm = myTree.getSelectionModel();
// // if (myTreesm.hasSelection()){
// // //check if has selection
// // var mynode = myTreesm.getSelection()[0];
// // //get first selection item
// // mynode.remove(true);
// // // True (for destroy the node)
// // } else {
// // Ext.Msg.alert('提示', "请先选择节点");
// // }
// //}
// }
// }]
// }
// );
// nodemenu.showAt(e.getXY());
// }
//}
添加节点,编辑节点我做的是在表单中弄.还可以判断增加的节点时子节点还是父节点。
//添加节点表单
Ext.define('MTTECERP.view.stomer.treeForm', {
extend:'Ext.form.Panel',
alias: 'widget.mynodeForm',
requires: [
'Ext.toolbar.Toolbar', 'Ext.toolbar.Fill',
'Ext.button.Button', 'Ext.form.field.Text',
'Ext.form.RadioGroup', 'Ext.form.field.Radio',
'MTTECERP.view.stomer.treeCtrl',
],
controller: 'nodeform',
border: false,
frame: true,
height: 100,
width: 323,
bodyPadding: 10,
header: false,
title: '',
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [
{xtype: 'tbfill'},
{ xtype: 'button', text: '保存', action: 'savenode', handler: 'savenewNode' },
//{ xtype: 'button', text: '保存', handler: 'savenewNode' },
//按钮状态
{ xtype: 'button', text: '停止', handler: 'closeform' }
]
}],
items: [{
xtype: 'textfield',
fieldLabel:'节点名字',
name:'nodetext',
anchor: '100%',
allowBlank: false,
enableKeyEvents: true,
listeners: {
keyup: function (o, e) {
if (e.button == 31) {
this.setValue(this.getValue() + " ");
}
}
}
},
//{
// xtype: 'radiogroup', fieldLabel: '是子节点么?',
// items: [
// {
// xtype: 'radiofield',
// name: 'usenodetype',
// boxLabel: '否',
// inputValue: 0
// },
// {
// xtype: 'radiofield',
// name: 'usenodetype',
// boxLabel: '是',
// inputValue: 1,
// checked: true
// }
// ]
//}
],
initComponent: function () {
this.callParent();
}
});
然后就是搞了很久的store,这是最坑的,api里面那么多的方法,以及传参数。
Ext.define('MTTECERP.view.stomer.wotreestore', {
extend: 'Ext.data.TreeStore',
model: 'MTTECERP.view.stomer.wotreemodel',
requires:'MTTECERP.view.stomer.wotreemodel',
type:'tree',
storeId: 'treeStore',
//autoLoad: true,
//autoSync: true,
proxy: {
type: 'ajax',
api: {
read:'http://localhost:8899/api/department/TreelistExt',
create:'http://localhost:8899/api/department/TreelistAdd',
//destroy:'http://localhost:8899/api/department/TreelistDel',
update:'http://localhost:8899/api/department/TreelistUpdate'
},
//actionMethods - 默认所有读数据请求(read)的方式为GET, 而所有写请求(create、update、destroy)的方式为POST)
actionMethods: {
create:'GET',
read:'GET',
update: 'GET',
//destroy: 'POST',
//destroy: 'GET'
},
reader: {
type: 'json',
//root:'data'
//rootProperty: 'Root',
//successProperty: 'success',
},
writer: {
type: 'json',
clientIdProperty: 'treeId',
writeAllFields: false, //just send changed fields
allowSingle: false
//rootproperty: 'Root',
//allowsingle: false,
//writeallfields: true,
//root: 'records'
},
listeners: {
write: function (store, operation, opts) {
console.log('wrote!');
//workaround to sync up store records with just completed operation
Ext.each(operation.records, function (record) {
if (record.dirty) {
record.commit();
}
});
},
update: function () {
console.log('tasks store updated');
}
}
},
});
//可用资源
//传参数方法1
//listeners: {
// 'beforeload': function (store, op, options) {
// var params = {
// ids:5,
// others:'555'
// };
// Ext.apply(store.proxy.extraParams, params);
// }
//},
//传参数方法2
//extraParams: {
// 'ids': ids,
// 'others': others
//},
//固定数据
//root: {
// text: '2334',
// expanded: true,
// rootVisible: true,
// children: [
// {
// text: '退货',
// id: 'mtt-1',
// children: [
// { leaf: true, text: '有瑕疵', id: 'mtt-2' }
// ]
// },
// {
// text: '换货',
// id: 'mtt-3',
// expanded: true,
// children: [
// { leaf: true, text: '破损', id: 'mtt-4' },
// { leaf: true, text: '发错了', id: 'mtt-5' },
// ]
// },
// {
// text: '退款',
// id: 'mtt-6',
// children: [
// { leaf: true, text: '补差价', id: 'mtt-7' },
// { leaf: true, text: '破损', id: 'mtt-8' },
// { leaf: true, text: '返现', id: 'mtt-9' }
// ]
// },
// { leaf: true, text: '补开发票', id: 'mtt-10' },
// { leaf: true, text: '其他', id: 'mtt-11' },
// ]
//},
然后还有tree对应的控制器,传参数,还有页面逻辑和发送请求,store.sync()就是同步Store与其proxy.每次操作执行完成后 更新Store内部的数据记录.
//控制的表单,在表单里进行的删除和新增
//var ids = null;
//var others = null;
Ext.define('MTTECERP.view.stomer.treeCtrl', {
alias:'controller.nodeform',
extend: 'Ext.app.ViewController',
refs: [{
ref: 'myform',
selector:'mynodeForm',
xtype:'mynodeForm',
autoCreate: false
},
{
ref: 'myalterform',
selector:'myalternodeForm',
xtype:'myalternodeForm',
autoCreate: false
},
],
savenewNode: function () {
var myTree = Ext.ComponentQuery.query('#stateTree')[0];
var addstore = myTree.getStore('treeStore');
var myTreesm = myTree.getSelectionModel();
if (myTreesm.hasSelection()) {
var mynode = myTreesm.getSelection()[0]
ids = parseInt(mynode.data.id)
} else {
var mynode = myTree.getRootNode();
}
//nodetext
var values = this.getView().getValues();
var newNode = {
text: values.nodetext,
leaf: true
};
other = values.nodetext
mynode.insertChild(0, newNode);
addstore.sync()
//传参数方法4
//bug
addstore.getProxy().extraParams = {
ids: parseInt(mynode.data.id),
other: values.nodetext
};
//addstore.new();
//这个方法回报错如下:addstore.new is not a function
},
//当有按钮的时候才会用到
closeform:function(){
var mybtn = Ext.ComponentQuery.query('#addnodebutton')[0];
//mybtn.menu.collapse();
mybtn.menu.close();
},
alterNode: function () {
console.log("编辑")
var myTree = Ext.ComponentQuery.query('#stateTree')[0];
var addstore = myTree.getStore('treeStore');
var myTreesm = myTree.getSelectionModel();
if (myTreesm.hasSelection()) {
//check if has selection
var mynode = myTreesm.getSelection()[0]
console.log(mynode.isLeaf())
ids = parseInt(mynode.data.id)
if (!mynode.isLeaf()) {
console.log(mynode.isLeaf())
Ext.Msg.alert("警告", "根节点部门不能编辑!")
} else {
var values = this.getView().getValues()
console.log(values)
var newNode = {
text: values,
};
other = values.nodetext
mynode.replaceChild(newNode, mynode);
addstore.getProxy().extraParams = {
ids: parseInt(mynode.data.id),
other: values.nodetext
};
addstore.update();
}
} else {
Ext.Msg.alert('提示', "请先选择节点");
}
},
//在有按钮的情况下使用
closealter: function () {
var mybtn = Ext.ComponentQuery.query('#addnodebutton')[0];
//mybtn.menu.collapse();
mybtn.menu.close();
},
});
//可用资源
//传参数方法3
//addstore.new({
// params:{
// ids:parseInt(mynode.data.id),
// others:values.nodetext
// }
//});
//addstore.new();
//更加优雅的写法?是吗?
//init: function() {
// this.control({
// 'button[action=savenode]': {
// click: this.savenewNode
// }
// });
//},
树的精华就是这样了。