Привязка к значениям вложенного массива в KendoUI TreeView
Мы оцениваем веб-сайт KendoUI для использования во всех наших проектах, и я столкнулся с проблемой (или отсутствием понимания) с виджетом TreeView.
Я пытаюсь использовать MVVM TreeView, и у меня возникают проблемы при привязке значений вложенного массива из моего шаблона. Я динамически строю древовидное представление, добавляя узел и его дочерние элементы нажатием кнопки. Я хочу привязать каждый конечный (дочерний) узел к текстовому значению на этом узле в MVVM. Кажется, это отлично работает при начальной загрузке дерева, но после добавления большего количества узлов в viewModel привязки перестают работать.
Это кажется намного сложнее, чем мне кажется, и это заставляет меня думать, что я что-то упустил.
Может ли кто-нибудь помочь пролить свет на это?
Спасибо,
Джейсон
JSFiddle
Я создал пример JSFiddle для нашего использования в этом обсуждении: http://jsfiddle.net/jsonsee/9B9pT/
HTML
<script id="treeTemplate" type="text/x-kendo-template">
<span>
#: item.name #
# if (!item.hasChilren) { #
<input type = 'text' data-bind = "value: treeData[#: item.parentIndex #].items[#: item.childIndex #].displayValue"/>
# } #
</span>
</script>
<div id="content">
<div id="form">
<label>Item Name:
<input type="text" data-bind="value: form.itemName" />
</label>
<button data-bind="click: form.onAddItem">Add Item</button>
<div class="console">
<h2>Output:</h2>
<div id="myConsole"/>
</div>
</div>
<h2>TreeView</h2>
<div data-template="treeTemplate" data-role="treeview" data-bind="source: treeData" />
</div>
Javascript
(function ($) {
var viewModel = kendo.observable({
itemIndex: 0,
form: {
itemName: '',
onAddItem: function (e) {
e.preventDefault();
var itemToAdd = {
name: viewModel.get('form.itemName'),
hasChilren: true,
items: (function () {
var children = [];
for (var i = 0; i < 3; i++) {
children.push({
name: viewModel.get('form.itemName') + '-child-' + i,
parentIndex: viewModel.get('itemIndex'),
childIndex: i,
displayValue: '',
hasChilren: false
});
}
return children;
})()
}
if (viewModel.get('treeData')) {
viewModel.get('treeData').push(itemToAdd);
} else {
viewModel.set('treeData', kendo.observableHierarchy([itemToAdd]));
}
viewModel.set('form.itemName', '');
viewModel.set('itemIndex', viewModel.get('itemIndex') + 1);
}
}
});
$(document).ready(function () {
kendo.bind(document.body, viewModel);
viewModel.bind('change', function (e) {
console.log('viewModel changed!');
var output = JSON.stringify(viewModel, undefined, 2);
console.log('----------------------------------------------------');
console.log(output);
console.log('----------------------------------------------------');
$("#myConsole").html("<pre>" + output + "</pre>");
});
});
})(jQuery);
редактировать
Обращаясь к комментарию:
В моем приложении я перетаскиваю элементы из палитры инструментов в левой части страницы в центральную панель. При отбрасывании предмета я строю дерево. У каждого узла есть набор детей, у этих детей нет детей. Таким образом, дерево имеет глубину на один уровень (два, если считать родителя).
Каждый узел в древовидной структуре отображается как таковой (начиная с родительского)
* parentNode.name
--->* childNode.name [textbox bound to this node's displayValue property in viewModel]
--->* childNode.name [textbox bound to this node's displayValue property in viewModel]
--->* childNode.name [textbox bound to this node's displayValue property in viewModel]
--->* childNode.name [textbox bound to this node's displayValue property in viewModel]
проблема
Часть, с которой у меня проблема - это привязка текстового поля дочерних узлов к свойству displayValue соответствующего поля viewModel в иерархическом источнике данных. Я перепробовал много разных методов, но тот, который "сортирует", работает с доступом к элементам массива непосредственно из привязки шаблона через: data-bind="value: treeData[#: item.parentIndex #]. Items[#: item.childIndex #].displayValue"
Обратите внимание, что приведенная выше привязка не работает после добавления второго узла. Это проблема. Я согласен, что код сложный, это одна из причин вопроса... что-то мне кажется неправильным. Итак, либо kendo MVVM не поддерживает прямую привязку к элементам вложенного массива, либо я делаю что-то совершенно не так.
Обновленный вывод
Я обновил JSFiddle и выкладываю вывод, чтобы лучше проиллюстрировать проблему. Обратите внимание, что второй набор дочерних элементов в viewModel имеет пустое свойство displayValue даже после того, как я изменил их в представлении. Привязки не работают по какой-то причине после добавления первого узла.
Новый JSFiddle: http://jsfiddle.net/jsonsee/9B9pT/
Распечатка viewModel
{
"itemIndex": 2,
"form": {
"itemName": ""
},
"treeData": [
{
"name": "a",
"hasChilren": true,
"items": [
{
"name": "a-child-0",
"parentIndex": 0,
"childIndex": 0,
"displayValue": "1",
"hasChilren": false,
"items": [],
"index": 0
},
{
"name": "a-child-1",
"parentIndex": 0,
"childIndex": 1,
"displayValue": "2",
"hasChilren": false,
"items": [],
"index": 1
},
{
"name": "a-child-2",
"parentIndex": 0,
"childIndex": 2,
"displayValue": "3",
"hasChilren": false,
"items": [],
"index": 2
}
],
"index": 0,
"expanded": true
},
{
"name": "b",
"hasChilren": true,
"items": [
{
"name": "b-child-0",
"parentIndex": 1,
"childIndex": 0,
"displayValue": "",
"hasChilren": false,
"index": 0
},
{
"name": "b-child-1",
"parentIndex": 1,
"childIndex": 1,
"displayValue": "",
"hasChilren": false,
"index": 1,
"selected": true
},
{
"name": "b-child-2",
"parentIndex": 1,
"childIndex": 2,
"displayValue": "",
"hasChilren": false,
"index": 2
}
],
"index": 1,
"expanded": true
}
]
}