Наблюдение свойств массива, наблюдаемого в KnockoutJS - PullRequest
9 голосов
/ 21 января 2011

Я работаю над приложением ASP.Net MVC. Мое действие - возвращать представление с моделью, представляющей собой массив объектов (класс со свойствами, такими как Name, ID, IsViewable).

var model = @Model.ToJson(); // done via extension call

Я хочу наблюдать за этим массивом, поэтому всякий раз, когда он изменяется, я могу обновить таблицу, которая была связана с шаблоном.

var viewModel = {
    accounts = ko.observableArray(model)
}

Это прекрасно работает для добавления и удаления элементов из массива. Однако я также хочу, чтобы шаблон обновлялся при изменении свойства одной из учетных записей (т. Е. Имени или идентификатора).

На веб-сайте KnockoutJS написано: Конечно, вы можете сделать эти свойства видимыми, если хотите, но это самостоятельный выбор . Это то, что я не могу понять, как это сделать.

Я пробовал что-то подобное безрезультатно:

var viewModel = {
    accounts = ko.oservableArray([])
}

for(var i = 0; i < model.length; i++) {
    ko.observableArray(model[i]);
    viewModel.accounts.push(model[i]);
}

Я могу опубликовать шаблон и таблицу, если это необходимо.

Ответы [ 3 ]

4 голосов
/ 28 января 2011

Вы должны заглянуть в плагин knockout.mapping . Я думаю, что это делает все, что вы хотите сделать.

4 голосов
/ 21 января 2011

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

Вам нужно обернуть элементы массива в класс JavaScript.Затем в конструкторе установите для каждого свойства значение obserable:

var model = @Model.ToJson();

var viewModel = {
    accounts = ko.observableArray(ko.utils.arrayMap(model, function(account) {
        return new AccountWrapper(account);
    }))
};

function AccountWrapper(account) {
    this.Property1 = ko.observable(account.Propery1);
    this.Property2 = ko.observable(account.Propery2);
    this.Property3 = ko.observable(account.Propery3);
}

ko.applyBindings(viewModel);

И если вы хотите изменить один из элементов, чтобы увидеть изменение, вы можете сделать что-то вроде:

viewModel.accounts()[3].Name('My Name Changed');

И вы все равно можете получать уведомления, когда элементы добавляются или удаляются:

viewModel.accounts.remove(viewModel.accounts()[4]);
0 голосов
/ 26 февраля 2011

Вот еще один подход, который работает и не требует подключаемого модуля:

var model = @Model.ToJson();

var viewModel = {
    accounts: ko.observableArray([]),

    fromJS: function(js) {
        for (var i = 0; i < js.length; i++) {
            this.accounts.push({ 
                Property1: ko.observable(js[i].Property1),
                Property2: ko.observable(js[i].Property2),
                Property3: ko.observable(js[i].Property3)
            });
        }
    }
};

viewModel.fromJS(model);
ko.applyBindings(viewModel);
...