Я заполняю древовидное представление из источника данных, предоставленного работником службы:
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, структура становится несколько сложной.
Это ожидаемое поведение согласно документация:
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>
@Марко, да, это тоже происходит из-за иерархического источника данных. Я не могу проверить это прямо сейчас, но вызывается ли событие check
после этого рендеринга или нет? Я имею в виду, после того, как дети получили ajax..
Ха! loadOnDemand:false
к спасению. В конце концов, ваше решение работает просто отлично, но мне пришлось заменить ваши jQuery и ecma на простые старые вызовы dojo/function. Это решает мою проблему независимо от возможных правил кодирования. Ты заслуживаешь пива. Ваше здоровье.
@Марко рад помочь моему другу!
Я столкнулся с проблемой, что локально
ul
с дочерними элементами фактически не отображается, когда узел свернут. Только когда вы расширяете узел, он действительно успешно запрашивает все дочерние элементы.