Как вызвать событие onCheck для дочерних узлов в Kendo TreeView, когда родитель проверен - PullRequest
1 голос
/ 10 апреля 2019

Я заполняю древовидное представление из источника данных, предоставленного работником сервиса:

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(). Поскольку этот виджет кендо должен быть реализован в виджете Dojo 1.10, структура имеет тенденцию становиться немного сложной.

1 Ответ

1 голос
/ 10 апреля 2019

Это ожидаемое поведение в соответствии с документацией :

Срабатывает после того, как пользователь установил или снял флажок.Если checkChildren имеет значение true, событие запускается после обновления всех проверенных состояний.

Таким образом, событие будет запускаться только один раз, независимо от того, сколько дочерних элементов было проверено.В вашем случае я бы обработал событие с помощью синтаксического анализатора, который перебирает все dataItems, вызывая событие _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>

Додзё

...