Как отменить отображение наблюдаемых массивов

У меня есть сложная модель представления, которая содержит несколько коллекций. Пользователи могут добавлять новые элементы в коллекции. Я вручную создаю модель представления и использую ko.mapping.fromJS для привязки данных с сервера. Коллекции могут быть пустыми или уже содержать значения.

Я ищу способ создать JSON из данных представления, чтобы отправить его обратно на сервер.

Когда я использую ko.mapping, JSON содержит только пустые объекты для добавленных элементов, потому что они не существовали в исходных данных.

Когда я использую ko.toJSON, JSON содержит свойство ko_mapping.

Я создал jsfiddle.

Кажется, одним из решений является использование ko.toJSON и удаление свойства ko_mapping, но я надеялся, что есть лучшее решение.

Код:

var initialData = {
   title: 'numbers:',
   numbers: []
   };

function Data() {
    var self = this;

    self.title = ko.observable();  
    self.numbers = ko.observableArray();

    self.addNumber = function() {
        self.numbers.push({
            id: ko.observable(2)
        });
    };

    self.removeNumber = function(item) {
        self.numbers.destroy(item);
    };
}

function ViewModel() {
    var self = this;
    self.masterData = [{
        id: 1,
        caption: "One"},
    {
        id: 2,
        caption: "Two"}];

    self.data = new Data();

    self.toMappedJSON = function() {
        var json = ko.mapping.toJSON(self.data);
        $('#json').text(js_beautify(json));
    };

   self.toJSON = function() {
       var json = ko.toJSON(self.data);
       $('#json').text(js_beautify(json));
   };    
}

var viewModel = new ViewModel();
ko.mapping.fromJS(initialData, {}, viewModel.data);

ko.applyBindings(viewModel);​

HTML:

<div data-bind="with: data">
<h2 data-bind="text: title"></h2>
    <ul data-bind="foreach: numbers">
        <li>
           <select data-bind="value: id, options: $root.masterData, optionsText: 'caption', optionsValue: 'id'"></select>
            value: <span data-bind="text: id"></span>
            <button data-bind="click: $parent.removeNumber">-</button>
        </li>
    </ul>
    <button data-bind="click: addNumber">+</button>
</div>

<h2>JSON</h2>
<div>
    <button data-bind="click: toMappedJSON">ko.mapping.toJSON</button>
    <button data-bind="click: toJSON">ko.toJSON</button>    
</div>
<textarea id="json" rows="15" cols="50"></textarea>

person delixfe    schedule 06.06.2012    source источник


Ответы (1)


Требование подключаемого модуля сопоставления, когда дело доходит до отмены сопоставления, заключается в том, что все объекты должны быть созданы с помощью подключаемого модуля. Когда вы добавляете элементы в массив, вы не создаете их с помощью подключаемого модуля сопоставления. Просто измените метод добавления на this.

self.addNumber = function() {
   self.numbers.push(ko.mapping.fromJS({
      id: ko.observable(2)
   }));
};

И это должно работать.

Надеюсь это поможет.

person madcapnmckay    schedule 06.06.2012