1

我目前在 zk 中使用动态树。代码如下:

<tree id="treeview"  multiple="true" width="330px" model="@load(vm.treeModel)"
                          style="border: 1px solid #9D9D9D;"  vflex="1" rows="14" >
                        <treecols sizable="true">
                            <treecol />
                        </treecols>
                        <template name="model">
                            <treeitem>
                                <treerow>
                                    <treecell><checkbox label="@load(each.data.name)" checked="true"/></treecell>
                                </treerow>
                            </treeitem>
                        </template>
                  </tree>

我希望如果我取消选中父复选框,则必须取消选中所有子项。反之亦然,即如果我选中父复选框,则必须选中所有子复选框。

zk 中的树标签是否有任何可用的属性来执行此操作?如果没有,还有什么其他方法可以做到这一点?

4

2 回答 2

0

我遇到了同样的问题,并想出了一个客户端唯一的解决方案,它可以快速准确地抛出正确的选择事件。

要启用它,请在您的树项渲染器中添加此小部件侦听器:

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;
}

(取消)选择一个树节点也将(取消)选择它的后代。此外,如果选择了所有节点的兄弟节点,则将选择父节点,否则不选择(这一直到根节点)。

于 2017-03-03T14:01:06.257 回答
0

您可以将 Zscript 用于您的目的,通过onclick链接到函数并将 Treeitem 作为参数传递的事件。该函数评估它是否有子级,循环遍历子级并根据是否选择父级进行设置。如果有很多嵌套的,您可以使用递归函数。

<zscript><![CDATA[
  public void selectItemsChildren(Treeitem item){
    item.setOpen(true);
    if(!item.isEmpty())
      for(Treeitem p : item.getTreechildren().getItems()){
        p.setSelected(item.isSelected());
      }
    }
  ]]>
</zscript> 
<tree id="treeAccess" width="100%" model="@bind(vm.treeModel)">
  <treecols>
    <treecol hflex="1" label="Description"/>
  </treecols>
  <template name="model">
    <treeitem onClick="selectItemsChildren(self)">
      <treerow>
        <treecell label="@load(each...any)"/>
      </treerow>
    </treeitem>
  </template>
</tree>
于 2020-10-22T02:23:44.223 回答