Knockoutjs TreeView Ленивая загрузка: дочерние узлы не отображаются - PullRequest
1 голос
/ 06 февраля 2012

Я только начал использовать knockoutjs и пытаюсь построить динамическое древовидное представление.Чтобы упростить, я удалил все, что не связано с проблемой.древовидная структура будет состоять из вложенных UL-тегов.

html:

<div id="pnlDestinations">
    <ul data-bind="template: { name: 'GroupTemplate', foreach: Groups }"></ul>
</div>

<script type="text/html" id="GroupTemplate">
    <li>
        <a href="#" data-bind="text: GroupName, click: function() { RetrieveDestinations($data); }"></a>
        <ul data-bind="template: { name: 'DestinationTemplate', foreach: Destinations }"></ul>
    </li>
</script>

<script type="text/html" id="DestinationTemplate">
    <li>
        <a href="#" data-bind="text: DestinationName"></a>
    </li>
</script>

код:

function ViewModel(groups) {
    Groups = ko.mapping.fromJS(groups);
    RetrieveDestinations = function (group) {
        $.getJSON('GetDestinations?id=' + group.GroupId(), function (data) {
            group.Destinations(ko.mapping.fromJS(data));
        });
    }
}

$(function () {
    $.getJSON("GetGroups", function (data) {
        ko.applyBindings(new ViewModel(data));
    });
});

Так что я связываю древовидную структуру на двух уровнях(используя 2 шаблона), но я получаю только один уровень в «GetGroups» (пункты назначения существуют, но это пустой массив).

Пункты назначения извлекаются в методах RetrieveDestination () при нажатии на группу идолжен заменить пустой массив в группе.Однако они не отображаются в моем древовидном представлении.

Привязка древовидного представления должна быть правильной, поскольку, если я включаю адресатов в «GetGroups», все отображается правильно.

1 Ответ

3 голосов
/ 07 февраля 2012

ko.mapping.fromJS когда данный массив собирается превратить его в observableArray.

Итак, когда вы делаете group.Destinations(ko.mapping.fromJS(data)), вы устанавливаете значение Destinations observableArray равным observableArray. По сути, это просто означает, что он обернут дважды.

Вы могли бы сделать что-то вроде group.Destinations(ko.mapping.fromJS(data)())

jsFiddle не позволяет сохранять в данный момент, но вот ваш код упрощен для использования подключаемого модуля для обновления адресатов (setTimeouts для имитации AJAX):

<div id="pnlDestinations">
    <ul data-bind="foreach: Groups">
        <li>
            <a href="#" data-bind="text: GroupName, click: $root.RetrieveDestinations"></a>
            <ul data-bind="foreach: Destinations">
                <li>
                    <a href="#" data-bind="text: DestinationName"></a>
                </li>        
            </ul>
        </li>
    </ul>
</div>

ViewModel:

function ViewModel(groups) {
    this.Groups = ko.mapping.fromJS(groups);
    this.RetrieveDestinations = function (group) {
        setTimeout(function() {
            //fake data
            var name = group.GroupName(),
                data = [ 
                    { DestinationName: name + "-1" }, 
                    { DestinationName: name + "-2" },
                    { DestinationName: name + "-3" }
                ];
            ko.mapping.fromJS(data, {}, group.Destinations);
            group.Destinations.push({ DestinationName: "new" });
        }, 100);
    };
}

$(function () {
    setTimeout(function() {
        var data = [
            { GroupName: "Group1", Destinations: [] },
            { GroupName: "Group2", Destinations: [] },
            { GroupName: "Group3", Destinations: [] }
            ];
        ko.applyBindings(new ViewModel(data));
    }, 100);     
});
...