получение многомерного массива (объекта), наблюдаемого в KnockoutJS

Я создаю приложение с помощью Knockout и считаю его очень полезным. Хотя у меня проблема с получением наблюдаемого многомерного массива (объекта).

На данный момент я использую следующую структуру:

    self.form = ko.observableArray(ko.utils.arrayMap(initialData, function(section) {
        var result = { 
            name : section.name, 
            code : section.code, 
            type : section.type, 
            fields: ko.observableArray(section.fields) 
        };
        return result;
    }));

Это работает хорошо, но я не могу заставить его работать, если initialData больше двух уровней. Я пробовал что-то вроде

    self.form = ko.observableArray(ko.utils.arrayMap(initialData, function(block) {
        var result = { 
            name : block.name, 
            code : block.code, 
            type : block.type, 
            sections: ko.observableArray(ko.utils.arrayMap(block.sections, function(section) {
                var result = { 
                    name : section.name, 
                    code : section.code, 
                    type : section.type, 
                    fields: ko.observableArray(section.fields) 
                };
                return result;
            }))
        };
        return result;
    }));

Окончательная структура массива выглядит хорошо, но нокаут не обновляет DOM, когда я делаю push в массив разделов:

    self.addField = function( section ) {
        field = {
            code: uid(),
            name: "New Field",
            value: '',
            type: section.type
        };
        section.fields.push(field); 
    };

Я также пробовал плагин Knockout.mapping.js (это правильный подход?) сначала выглядит хорошо, но после нажатия в приведенной выше функции мой новый элемент поля не наблюдается, просто объект.

В документации плагина сказано:

// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);

Но я не уверен, что это мой случай.

Если у кого-то есть идеи, было бы очень признательно.

Спасибо.

UPD: Сделать наблюдаемыми 1-й и 2-й уровни не проблема, проблема углубиться.

Вот пример initialData:

var blocks = [
    {
        "name" : "",
        "sections" : [
            {
                "name" : "Section 1",
                "fields" : [
                    {
                        "name" : "Field A",
                        "type" : "checkbox",
                        "code" : uid()
                    }
                ]
            }
        ]
    }
];

HTML

<div data-bind='template: { name: tpl-form-field-checkbox, foreach: fields }'></div>
<button class="btn addField" data-bind="click: $root.addField">Add</button>

<script type="text/html" id="tpl-form-field-checkbox">
    <input type="text" name="" value="<%= name %>" /> <br/>
</script> 

person Pavel    schedule 27.05.2012    source источник
comment
Было бы полезно увидеть пример для initialData, если это возможно.   -  person janfoeh    schedule 27.05.2012
comment
Кроме того, можете ли вы опубликовать выдержку из ваших привязок данных HTML?   -  person janfoeh    schedule 27.05.2012
comment
Я обновил вопрос, спасибо.   -  person Pavel    schedule 27.05.2012
comment
Если вы хотите, чтобы ваше новое имя поля было наблюдаемым, вам придется использовать ko.observable('New Field') чтобы сделать его наблюдаемым. Простое добавление объекта в observableArray не делает этот объект (или его свойства) наблюдаемыми.   -  person John Earles    schedule 27.05.2012
comment
Спасибо, Джон, теперь я понял. Я использую плагин сопоставления и понял, что мне нужно игнорировать некоторые свойства объекта JS (чтобы не отображать их).   -  person Pavel    schedule 27.05.2012


Ответы (1)