如何 check/uncheck 树面板的所有节点,然后只向 extjs 中的服务器发送请求?
How to check/uncheck all nodes of tree panel and after that only send request to server in extjs?
我是 extjs
的新手,我使用过树面板。我已经编写了用于选中和取消选中树控件复选框的代码。我的树结构如下所示。
|-Parent 1
|- Child 1
|- Child 2
|- Sub child 2.1
|- Sub child 2.2
|- Child 3
|- Child 4
|- Sub child 4.1
|- Sub child 4.2
|- Child 5
|- Child 6
|-Parent 2
|- Child 1
|- Child 2
|- Sub child 2.1
|- Child 3
在侦听器中,我编写了用于检查和取消选中节点的代码,假设如果选择了所有节点并且用户取消选中 Sub child 2.3
,则 Child 2
和 Parent 1
都取消选中并且工作正常。
现在的问题是每当这个 check/uncheck 事件发生时,它都会触发数据库调用。我想让它像一次让它完成所有 check/uncheck 操作,然后单次调用数据库而不是每次调用。我很困惑如何实现它?下面是相同的代码。
items: [
Ext.create('Ext.tree.Panel', {
checkPropagation: 'both',
itemId: 'datasourceCustodianTree',
rootVisible: false,
store: {
fields: ['value'],
root: {
expanded: true,
children: treeData,
text: 'Source:',
}
},
listeners: {
checkchange: function (node, checked, options) {
var list1 = [], list2 = [], list3 = [];
var tree = me.down('#datasourceTree');
// Propagate change downwards (for all children of current node).
var setChildrenCheckedStatus = function (current) {
if (current.parentNode) {
var parent = current.parentNode;
current.set('checked', parent.get('checked'));
suspendEvent = true;
}
if (current.hasChildNodes()) {
current.eachChild(arguments.callee);
}
};
if (node.hasChildNodes()) {
node.eachChild(setChildrenCheckedStatus);
}
// Propagate change upwards (if all siblings are the same, update parent).
var updateParentCheckedStatus = function (current) {
if (current.parentNode) {
var parent = current.parentNode;
var checkedCount = 0;
parent.eachChild(function (n) {
checkedCount += (n.get('checked') ? 1 : 0);
});
// Children have same value if all of them are checked or none is checked.
var sameValue = (checkedCount == parent.childNodes.length) || (checkedCount == 0);
if (sameValue) {
var checkedValue = (checkedCount == parent.childNodes.length);
parent.set('checked', checkedValue);
suspendEvent = true;
} else {
// Not all of the children are checked, so uncheck the parent.
parent.set('checked', false);
suspendEvent = false;
}
updateParentCheckedStatus(parent);
}
}
updateParentCheckedStatus(node);
this.getChecked().forEach(function (item) {
if (item.data.parentId !== "root" && item.isLeaf()) {
if (item.data.listFor.toLowerCase() === 'item1') {
list1.push(item.data.value);
} else if (item.data.listFor.toLowerCase() === 'item2') {
list2.push(item.data.value);
} else if (item.data.listFor.toLowerCase() === 'item3') {
list3.push(item.data.value);
}
}
});
// DB Call to get data on any checkchange event.
me.updateData(list1, list2, list3);
}
}
})
]
如何进行这样的操作?我尝试制作 suspendEvent('checkchange');
之后 resumeEvent('checkchange')
。但这不起作用,因为它只会调用此事件一次。
现在一头雾水,怎么办?
为此,您不需要 extjs 的任何技巧。只需像这样设置一个控制变量,以便事件处理程序仅在手动 check/uncheck 操作后工作。
checkchange: function(){
if(this._suspendCheckChange){
return;
}
this._suspendCheckChange = true;
// your check/uncheck logic
// ...
this._suspendCheckChange = false;
}
我已进行调查,问题出在我的代码中。我使用了一个 属性,我不知道它会做什么,我已经删除了那个 属性。删除此 属性,一切正常。 checkPropagation: 'both'
适用于 extangular。
组件 UI
<ExtTree fitToParent="true" cls="red-node-text" [store]="treeStore" (select)="onSelect($event)" (checkchange)="onCheckchange($event)">
</ExtTree>
关于组件 ts
onCheckchange = ({ cell, checked, record, e }) => {
if(record.hasChildNodes()){
record.eachChild(function(n){n.set('checked', checked);} );
}
};
我是 extjs
的新手,我使用过树面板。我已经编写了用于选中和取消选中树控件复选框的代码。我的树结构如下所示。
|-Parent 1
|- Child 1
|- Child 2
|- Sub child 2.1
|- Sub child 2.2
|- Child 3
|- Child 4
|- Sub child 4.1
|- Sub child 4.2
|- Child 5
|- Child 6
|-Parent 2
|- Child 1
|- Child 2
|- Sub child 2.1
|- Child 3
在侦听器中,我编写了用于检查和取消选中节点的代码,假设如果选择了所有节点并且用户取消选中 Sub child 2.3
,则 Child 2
和 Parent 1
都取消选中并且工作正常。
现在的问题是每当这个 check/uncheck 事件发生时,它都会触发数据库调用。我想让它像一次让它完成所有 check/uncheck 操作,然后单次调用数据库而不是每次调用。我很困惑如何实现它?下面是相同的代码。
items: [
Ext.create('Ext.tree.Panel', {
checkPropagation: 'both',
itemId: 'datasourceCustodianTree',
rootVisible: false,
store: {
fields: ['value'],
root: {
expanded: true,
children: treeData,
text: 'Source:',
}
},
listeners: {
checkchange: function (node, checked, options) {
var list1 = [], list2 = [], list3 = [];
var tree = me.down('#datasourceTree');
// Propagate change downwards (for all children of current node).
var setChildrenCheckedStatus = function (current) {
if (current.parentNode) {
var parent = current.parentNode;
current.set('checked', parent.get('checked'));
suspendEvent = true;
}
if (current.hasChildNodes()) {
current.eachChild(arguments.callee);
}
};
if (node.hasChildNodes()) {
node.eachChild(setChildrenCheckedStatus);
}
// Propagate change upwards (if all siblings are the same, update parent).
var updateParentCheckedStatus = function (current) {
if (current.parentNode) {
var parent = current.parentNode;
var checkedCount = 0;
parent.eachChild(function (n) {
checkedCount += (n.get('checked') ? 1 : 0);
});
// Children have same value if all of them are checked or none is checked.
var sameValue = (checkedCount == parent.childNodes.length) || (checkedCount == 0);
if (sameValue) {
var checkedValue = (checkedCount == parent.childNodes.length);
parent.set('checked', checkedValue);
suspendEvent = true;
} else {
// Not all of the children are checked, so uncheck the parent.
parent.set('checked', false);
suspendEvent = false;
}
updateParentCheckedStatus(parent);
}
}
updateParentCheckedStatus(node);
this.getChecked().forEach(function (item) {
if (item.data.parentId !== "root" && item.isLeaf()) {
if (item.data.listFor.toLowerCase() === 'item1') {
list1.push(item.data.value);
} else if (item.data.listFor.toLowerCase() === 'item2') {
list2.push(item.data.value);
} else if (item.data.listFor.toLowerCase() === 'item3') {
list3.push(item.data.value);
}
}
});
// DB Call to get data on any checkchange event.
me.updateData(list1, list2, list3);
}
}
})
]
如何进行这样的操作?我尝试制作 suspendEvent('checkchange');
之后 resumeEvent('checkchange')
。但这不起作用,因为它只会调用此事件一次。
现在一头雾水,怎么办?
为此,您不需要 extjs 的任何技巧。只需像这样设置一个控制变量,以便事件处理程序仅在手动 check/uncheck 操作后工作。
checkchange: function(){
if(this._suspendCheckChange){
return;
}
this._suspendCheckChange = true;
// your check/uncheck logic
// ...
this._suspendCheckChange = false;
}
我已进行调查,问题出在我的代码中。我使用了一个 属性,我不知道它会做什么,我已经删除了那个 属性。删除此 属性,一切正常。 checkPropagation: 'both'
适用于 extangular。
组件 UI
<ExtTree fitToParent="true" cls="red-node-text" [store]="treeStore" (select)="onSelect($event)" (checkchange)="onCheckchange($event)">
</ExtTree>
关于组件 ts
onCheckchange = ({ cell, checked, record, e }) => {
if(record.hasChildNodes()){
record.eachChild(function(n){n.set('checked', checked);} );
}
};