我遇到了同样的问题,并想出了一个客户端唯一的解决方案,它可以快速准确地抛出正确的选择事件。
要启用它,请在您的树项渲染器中添加此小部件侦听器:
treeitem.setWidgetListener(Events.ON_CLICK, "selectSubTreesOnItemClick(this, event);");
在您的情况下(模板),请这样做:
<tree xmlns:w="client">
...
<treeitem w:onClick="selectSubTreesOnItemClick(this, event)">
然后,导入以下 js 文件(在您的 zul 中,添加<script src="/js/treeselection.js" />
某处):
function selectSubTreesOnItemClick(item, event) {
// if clicked outside of check box, reset selection
if (!jq(event.target).is('.z-treerow')) {
item.getTree().clearSelection();
// re-select clicked node
item.setSelected(true);
}
privateSelectDescendants(item);
privateSelectParentIfAllDescendantsSelected(item);
// update selection
item.getTree().fireOnSelect(item);
// prevent interference of the tree's default click behavior (like selection of the clicked node ;) ).
event.stop();
}
/**
* @param parent if selected, selects all children (and grand-children and so on), otherwise
* removes them from selection.
*/
function privateSelectDescendants(parent) {
var items = parent.getTree().itemIterator();
// find all descendants of parent
while (items.hasNext() && items.next() !== parent) {}
var stopAt = privateGetFirstNonDescendant(parent);
// check descendants
while (items.hasNext()) {
var descendant = items.next();
if (descendant === stopAt) {
break;
} else {
descendant.setSelected(parent.isSelected());
}
}
}
/**
* @param item parent will be selected if item and all its siblings are selected, otherwise
* unselected. Repeated for grandparents, great-grandparents, and so on.
*/
function privateSelectParentIfAllDescendantsSelected(item) {
if (item.getParentItem() != null) {
var parent = item.getParentItem();
// find all descendants of parent
var items = parent.getTree().itemIterator();
while (items.hasNext()) {
if (items.next() === parent){
break;
}
}
var stopAt = privateGetFirstNonDescendant(parent);
// check descendants
var allDescendantsSelected = true;
while (items.hasNext()) {
var child = items.next();
if (child === stopAt) {
break;
} else if (!child.isSelected()) {
allDescendantsSelected = false;
break;
}
}
parent.setSelected(allDescendantsSelected);
// continue with grandparents
privateSelectParentIfAllDescendantsSelected(parent);
}
}
/**
* @param item
* @returns the next item that is on the same or a higher level as item.
* Undefined if item is the last node or only followed by children.
*/
function privateGetFirstNonDescendant(item) {
var result = item.nextSibling;
while (!result && item.getParentItem() != null) {
item = item.getParentItem();
result = item.nextSibling;
}
return result;
}
(取消)选择一个树节点也将(取消)选择它的后代。此外,如果选择了所有节点的兄弟节点,则将选择父节点,否则不选择(这一直到根节点)。