【问题标题】:How to trigger the onCheck event for child nodes in Kendo TreeView, when parent is checked选中父节点时如何在 Kendo TreeView 中触发子节点的 onCheck 事件
【发布时间】:2019-04-10 11:43:56
【问题描述】:

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

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 小部件中实现,因此结构往往会变得有点复杂。

【问题讨论】:

    标签: javascript kendo-ui kendo-treeview


    【解决方案1】:

    这是documentation 的预期行为:

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

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

    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>

    Dojo

    【讨论】:

    • 我面临的问题是,当节点折叠时,本地的 ul 与子节点实际上并没有渲染。只有当你展开一个节点时,它才会真正成功地查询到所有子节点
    • @Marco 是的,这也是因为分层数据源。我现在无法测试它,但是在渲染之后是否会调用 check 事件?我的意思是,在孩子们通过 ajax 获取之后..
    • 哈! loadOnDemand:false 救援。最后,您的解决方案工作得很好,但是我不得不用普通的旧 dojo / 函数调用替换您的 jQuery 和 ecma 优点。无论最终的编码指南如何,它都能解决我的问题。你值得喝啤酒。干杯。
    • @Marco 很高兴能帮助我的朋友!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    相关资源
    最近更新 更多