Вычисленный массив Knockout.js не срабатывает при изменении

Я пытаюсь создать редактируемую сетку с вычисленным observableArray в MVC 4 и Knockout.js. Метод calculated() вызывается при первой загрузке массива, но не при изменении каких-либо данных в сетке посредством редактирования пользователем.

Модель представления:

function CarsVm() {
var self = this;

self.url = 'http://localhost/FederatedWcf/Services/RestCars.svc/json/cars';

self.cars = ko.observableArray([]);

self.car = ko.computed(function () {
    if ( this.cars().length > 0)
        return this.cars()[this.cars().length-1].Make;
    else {
        return "";
    }
}, this);

self.GetCars = function () {
    var count = 0;
    $.getJSON(self.url, function (allData) {
        var mappedCars = $.map(allData.JsonCarsResult, function (item) {
            console.log(count);
            console.log(item);
            count = count + 1;
            return new Cars(item);
        });
        self.cars(mappedCars);
        console.log(self.cars());
    });
    $.ajaxSetup({ cache: false });
};

}

И фрагмент html:

<table>
<thead>
    <tr>
        <th></th>
        <th>Year</th>
        <th>Make</th>
        <th>Model</th>
        <th></th>
    </tr>
</thead>
<tbody data-bind="foreach: cars">
    <tr>
        <td><span style="display:none" data-bind="text:Id"></span></td>
        <td><input data-bind="value:Year"></input></td>
        <td><input data-bind="value:Make"></input></td>
        <td><input data-bind="value:Model"></input></td>
        <td><button data-bind="click: $root.removeCar">-</button></td>
    </tr>
</tbody>
</table>
<span data-bind="text:car"></span>

Если я редактирую последнюю марку в сетке, я ожидал, что элемент автомобиля с привязкой к данным будет обновлен, но это не так.

Как обнаружить изменения в сетке, например, во время события onblur, в нокаутирующем массивеObservableArray?


person Steve    schedule 21.02.2013    source источник


Ответы (2)


Обязательно пометьте каждое свойство в Cars как наблюдаемое, иначе нокаут не заметит, что они изменились.

function Cars(data) {
   var self = this;
   self.Id = data.Id;
   self.Year = ko.observable(data.Year);
   self.Make = ko.observable(data.Make);
   self.Model = ko.observable(data.Model);
}
person Boone    schedule 21.02.2013

Это потому, что когда вы изменяете свойства объектов в cars, observableArray ничего не наблюдает (он по-прежнему содержит те же объекты, верно?)

Чтобы он знал о свойствах, вы должны сделать каждый элемент в observableArray наблюдаемым. Вы можете сделать это с помощью собственного плагина сопоставления или вручную с помощью ko.observable() в вашей текущей функции сопоставления.

person Fabian Schmengler    schedule 21.02.2013