当选中父级时,如何在Kendo TreeView中触发子节点的onCheck事件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当选中父级时,如何在Kendo TreeView中触发子节点的onCheck事件相关的知识,希望对你有一定的参考价值。

我正在从服务工作者提供的数据源填充树视图:

postCreate: function () {
    var self = this;
    self._loadLayerConfiguration()
        .then(function (data) {
            self.layerConfig = data;
            self._treeView = $("#LayerList").kendoTreeView({
                dataValueField: "Id",
                dataTextField: "Title",
                checkboxes: {
                    checkChildren: true
                },

                check: self._onCheck.bind(self),
                dataSource: new kendo.data.HierarchicalDataSource({ /*...*/}
                })
            });
        });
},

如您所见,配置已设置,以便在检查父元素时检查所有子元素,然后触发_onCheck方法。

现在,此方法应该对正在更改的每个复选框起作用:

_onCheck: function (e) {
    var dataItem = this._treeView.data("kendoTreeView").dataItem(e.node);
    if (!dataItem.layer && dataItem.Url !== null) { //Url is null, if this is a Group layer
        //load FeatureLayer, if not loaded
        //load legend, if not loaded
        //add to map
        //omitted for brevity
    }
    dataItem.layer.setVisibility(dataItem.checked);
    this._checkChildren.call(this, dataItem);
},

这里的问题是,onCheck事件仅针对用户直接点击的节点触发,而不是针对受其影响的所有子节点触发。

我试图递归遍历dataItem的所有子项并手动触发检查事件,但无济于事:

_checkChildren: function (dataItem) {
    var self = this;
    if (dataItem.hasChildren) {
        var children = dataItem.children.data();
        children.forEach(function (child) {
            child.set("checked", dataItem.checked);

            //self._treeView.trigger("check", {
            //  node: self._treeView.findByUid(child.uid)
            //});
            if (child.hasChildren) {
                //recurse
                self._checkChildren.call(self, child);
            }
        });
    }
},

结果是,为树视图中的直接更改复选框引发了事件,但不是其子项。孩子们只接受检查。触发受父节点影响的所有子节点的检查事件的正确方法是什么?

请不要被.bind().call()调用所激怒。由于此kendo小部件必须实现为Dojo 1.10小部件,因此结构往往会变得有点复杂。

答案

根据documentation,这是预期的行为:

用户选中或取消选中复选框后触发。如果checkChildren为true,则在更新所有已检查状态后触发事件。

因此,无论检查了多少孩子,事件都只会触发一次。在您的情况下,我要做的是使用解析器来处理事件,以遍历所有为每个调用_onCheck事件的dataItem:

check: function(e) {
    _onCheck(this.dataItem(e.node));

    $(e.node).find("li").each((i, node) => _onCheck(this.dataItem(node)));
}

_onCheck: function _onCheck(dataItem) {
    console.log(dataItem);
};

工作演示:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.common.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.rtl.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.silver.min.css"/>
    <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.mobile.all.min.css"/>

    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="https://kendo.cdn.telerik.com/2019.1.220/js/kendo.all.min.js"></script>
</head>
<body>
  
<div id="treeview"></div>
<script>
  let _onCheck = function _onCheck(dataItem) {
    console.log(dataItem);
  };
  
$("#treeview").kendoTreeView({
  checkboxes: {
    checkChildren: true
  },
  dataSource: [
    { text: "foo", items: [
      { text: "bar" }
    ] }
  ],
  check: function(e) {
    _onCheck(this.dataItem(e.node));
    
    $(e.node).find("li").each((i, node) => _onCheck(this.dataItem(node)));
  }
});
</script>
</body>
</html>

以上是关于当选中父级时,如何在Kendo TreeView中触发子节点的onCheck事件的主要内容,如果未能解决你的问题,请参考以下文章

仅在父级时删除之前发布

Swift 3.0:当给定非 SKView 父级时,SKSpriteNode 作为 Button 不起作用?

如何有效地通过 React 中父级的引用访问子级?

Hibernate @OneToMany 在更新父级时从列表中删除子级

在 SpriteKit 中添加到父级时未显示未归档节点

在 Kendo 中为 Angular TreeView 获取节点元数据