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

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

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, структура становится несколько сложной.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
1 275
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Triggered after the user has checked or unchecked a checkbox. If checkChildren is true, the event is triggered after all checked states are updated.

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

Додзё

Я столкнулся с проблемой, что локально ul с дочерними элементами фактически не отображается, когда узел свернут. Только когда вы расширяете узел, он действительно успешно запрашивает все дочерние элементы.

Marco 10.04.2019 14:18

@Марко, да, это тоже происходит из-за иерархического источника данных. Я не могу проверить это прямо сейчас, но вызывается ли событие check после этого рендеринга или нет? Я имею в виду, после того, как дети получили ajax..

DontVoteMeDown 10.04.2019 14:22

Ха! loadOnDemand:false к спасению. В конце концов, ваше решение работает просто отлично, но мне пришлось заменить ваши jQuery и ecma на простые старые вызовы dojo/function. Это решает мою проблему независимо от возможных правил кодирования. Ты заслуживаешь пива. Ваше здоровье.

Marco 10.04.2019 14:32

@Марко рад помочь моему другу!

DontVoteMeDown 10.04.2019 14:41

Другие вопросы по теме