在ExtJs 4树面板中取消选择节点子节点的内置方法
我使用的是ExtJs树面板。当您选择某个节点时,是否有任何内置方法或属性将取消选择该节点的所有子节点在ExtJs 4树面板中取消选择节点子节点的内置方法,extjs,tree,extjs4,Extjs,Tree,Extjs4,我使用的是ExtJs树面板。当您选择某个节点时,是否有任何内置方法或属性将取消选择该节点的所有子节点 考虑下面的图像,假设已经选择了黄色背色的节点。如果我现在选择1.1,系统应该自动取消选择1.1.2&如果我选择了节点1,它应该取消选择1.1.2、.1.2.1、1.2.2 请提供您的建议 Ext.create('Ext.tree.Panel', { title: 'Simple Tree', renderTo: Ext.getBody(), width: 400,
考虑下面的图像,假设已经选择了黄色背色的节点。如果我现在选择1.1,系统应该自动取消选择1.1.2&如果我选择了节点1,它应该取消选择1.1.2、.1.2.1、1.2.2
请提供您的建议Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
renderTo: Ext.getBody(),
width: 400,
height: 400,
store: {
root: {
expanded: true,
children: [{
text: "1 detention",
expanded: true,
"checked": false,
children: [{
text: '1.1 foo',
leaf: true,
"checked": false
}, {
text: '1.2 bar',
leaf: true,
"checked": false
}]
}, {
text: "2 homework",
expanded: true,
"checked": false,
children: [{
text: "2.1 book report",
leaf: true,
"checked": false
}, {
text: "2.2 algebra",
expanded: true,
"checked": false,
children: [{
text: "2.2.1 buy lottery tickets",
leaf: true,
"checked": false
}, {
text: "2.2.2 buy lottery tickets 2",
leaf: true,
"checked": false
}]
}]
}, {
text: "3 buy lottery tickets",
leaf: true,
"checked": false
}]
}
},
useArrows: false,
rootVisible: false,
selModel: {
mode: 'SIMPLE'
},
listeners: {
deselect: function (tree, record) {
if (record.data.text === '1 detention') {
}
},
select: function (tree, record) {
var parentNode = record.parentNode;
// Deselect children
function deselectChildren(record) {
tree.deselect(record.childNodes, false);
record.eachChild(deselectChildren);
}
deselectChildren(record);
// See if all siblings are selected now
var allSiblingSelected = false;
if (parentNode) {
allSiblingSelected = parentNode.childNodes.reduce(function (previous, node) {
return previous && tree.isSelected(node)
}, true);
}
if (allSiblingSelected) {
tree.select(parentNode, true); // will trigger req 1
}
// Deselect ancestors
else {
while (parentNode) {
tree.deselect(parentNode);
parentNode = parentNode.parentNode;
}
}
}
}
});
不,没有这种内置的东西。哦,现在我想起来了,有一些事件是内置在Ext中的。你可以捕捉到一个事件并在其中实现你自己的逻辑!在你的情况下,就是这样 以下是我建议您完全按照您所描述的方式(使用文档中的示例树面板): 但这给了我们一个非常奇怪的用户体验,因为一旦选择了父节点,就可以再次选择子节点。。。要触发该行为(通过再次单击子节点的祖先节点来取消选择子节点),您必须首先取消选择父节点,然后重新选择它。。。简言之,依我看,这令人困惑 因此,为了让用户更容易预测所有这些内容,我建议在选择节点时通过以下方式更改
select
侦听器来取消选择所有祖先:
select: function(tree, record) {
// Deselect children
function deselectChildren(record) {
tree.deselect(record.childNodes);
record.eachChild(deselectChildren);
}
deselectChildren(record);
// Deselect ancestors
var parentNode = record.parentNode;
while (parentNode) {
tree.deselect(parentNode);
parentNode = parentNode.parentNode;
}
}
或阻止选择已选择祖先的节点:
listeners: {
select: function(tree, record) {
function deselectChildren(record) {
tree.deselect(record.childNodes);
record.eachChild(deselectChildren);
}
deselectChildren(record);
}
// Returning false from this event handler will prevent selection (see the doc)
,beforeselect: function(tree, record) {
function isAncestorSelected(record) {
var parentNode = record.parentNode;
return tree.isSelected(record) || parentNode && isAncestorSelected(parentNode);
}
return !isAncestorSelected(record);
}
}
但是,如果你想听听我的意见,第二种行为也有点古怪。我会用第一个
现在,如果您愿意,您可以将所有这些打包到ux(用户扩展)中,在Sencha市场上发布,从那里下载,并在代码中使用。。。那样的话,你的行为就会被植入某种东西中;)
编辑
要求1+2+3的代码
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
renderTo: Ext.getBody(),
width: 400,
height: 400,
store: {
root: {
expanded: true,
children: [
{ text: "detention", leaf: true },
{ text: "homework", expanded: true, children: [
{ text: "book report", leaf: true },
{ text: "algebra", expanded: true, children: [
{ text: "buy lottery tickets", leaf: true }
]}
] },
{ text: "buy lottery tickets", leaf: true }
]
}
},
rootVisible: false,
selModel: {
mode: 'SIMPLE'
},
listeners: {
select: function(tree, record) {
var parentNode = record.parentNode;
// Deselect children
function deselectChildren(record) {
tree.deselect(record.childNodes);
record.eachChild(deselectChildren);
}
deselectChildren(record);
// See if all siblings are selected now
var allSiblingSelected = false;
if (parentNode) {
allSiblingSelected = parentNode.childNodes.reduce(function(previous, node) {
return previous && tree.isSelected(node)
}, true);
}
if (allSiblingSelected) {
// EDIT3: adding true for second argument keepExisting
tree.select(parentNode, true); // will trigger req 1
}
// Deselect ancestors
else {
while (parentNode) {
tree.deselect(parentNode);
parentNode = parentNode.parentNode;
}
}
}
}
});
编辑4
带有复选框:
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
renderTo: Ext.getBody(),
width: 400,
height: 400,
store: {
root: {
expanded: true,
children: [
{ checked: false, text: "1 detention", expanded: true, children: [
{checked: false, text: '1.1 foo', leaf: true},
{checked: false, text: '1.2 bar', leaf: true}
] },
{ checked: false, text: "2 homework", expanded: true, children: [
{ checked: false, text: "2.1 book report", leaf: true },
{ checked: false, text: "2.2 algebra", expanded: true, children: [
{ checked: false, text: "2.2.1 buy lottery tickets", leaf: true },
{ checked: false, text: "2.2.2 buy lottery tickets 2", leaf: true }
]}
] },
{ checked: false, text: "3 buy lottery tickets", leaf: true }
]
}
},
rootVisible: false,
disableSelection: true,
//selModel: {mode: 'SIMPLE'},
listeners: {
checkchange: function(record, checked, opts) {
if (!checked) return;
var parentNode = record.parentNode;
// Deselect children
function deselectChildren(record) {
record.eachChild(function(record) {
record.set('checked', false);
deselectChildren(record);
});
}
deselectChildren(record);
// See if all siblings are selected now
var allSiblingSelected = false;
if (parentNode) {
allSiblingSelected = parentNode.childNodes.reduce(function(previous, node) {
return previous && node.get('checked');
}, true);
}
if (allSiblingSelected) {
parentNode.set('checked', true);
// Apparently won't fire on its own
this.fireEvent('checkchange', parentNode, true, opts);
}
// Deselect ancestors
else {
while (parentNode) {
parentNode.set('checked', false);
parentNode = parentNode.parentNode;
}
}
}
}
});
我没有提出全部要求,因为这会使这个问题变得非常复杂。其思想是,1)当您选择一个节点时,我们需要取消选择其整个子节点(直接或间接)。2) 当您选择所有子节点或节点时,我们需要自动选择其父节点并取消选择所有子节点,因此。。。这个答案对你有帮助吗?你的第二个要求也需要帮助吗?你想或计划如何处理我揭露的这个有问题的案子?即,在选择父节点后选择子节点。你对此只字未提,如果你什么也不做,最终可能会同时选择父节点和子节点,这显然是你想要避免的…老实说,我仍在努力理解你发送的代码:-)。但是,如果你真的看第二个需求,第一个需求会处理它。当一个节点的所有兄弟节点都被选中时,我所需要做的就是选择父节点,第一个需求本身将为我完成这个任务。谢谢你是的,那样的话就行了,但是让我恼火的情况如下。在您的示例中,如果选择节点1.1,将取消选择节点1.1.1、1.1.2和1.1.3,这是第一个要求。但是如果现在我选择节点1.1.2呢?这不会触发您的任何一个需求,但是我们将在选择节点1.1的同时选择它的子节点1.1.2。看到了吗?当我们选择一个节点时,我们需要查看它的所有同级节点是否都被选中。如果是,请选择它的父节点(选择父节点将取消选择子节点)。如果否,请选择此节点并取消选择父节点。我本应解释所有这些情况,但我担心问题会变得混乱,我可能得不到任何答复。
Ext.create('Ext.tree.Panel', {
title: 'Simple Tree',
renderTo: Ext.getBody(),
width: 400,
height: 400,
store: {
root: {
expanded: true,
children: [
{ checked: false, text: "1 detention", expanded: true, children: [
{checked: false, text: '1.1 foo', leaf: true},
{checked: false, text: '1.2 bar', leaf: true}
] },
{ checked: false, text: "2 homework", expanded: true, children: [
{ checked: false, text: "2.1 book report", leaf: true },
{ checked: false, text: "2.2 algebra", expanded: true, children: [
{ checked: false, text: "2.2.1 buy lottery tickets", leaf: true },
{ checked: false, text: "2.2.2 buy lottery tickets 2", leaf: true }
]}
] },
{ checked: false, text: "3 buy lottery tickets", leaf: true }
]
}
},
rootVisible: false,
disableSelection: true,
//selModel: {mode: 'SIMPLE'},
listeners: {
checkchange: function(record, checked, opts) {
if (!checked) return;
var parentNode = record.parentNode;
// Deselect children
function deselectChildren(record) {
record.eachChild(function(record) {
record.set('checked', false);
deselectChildren(record);
});
}
deselectChildren(record);
// See if all siblings are selected now
var allSiblingSelected = false;
if (parentNode) {
allSiblingSelected = parentNode.childNodes.reduce(function(previous, node) {
return previous && node.get('checked');
}, true);
}
if (allSiblingSelected) {
parentNode.set('checked', true);
// Apparently won't fire on its own
this.fireEvent('checkchange', parentNode, true, opts);
}
// Deselect ancestors
else {
while (parentNode) {
parentNode.set('checked', false);
parentNode = parentNode.parentNode;
}
}
}
}
});