Как отобразить на массив, поступающий от объекта сервера с помощью плагина Knockout Mapping, и есть некоторые вычисленные?

Чтение этого обмена в stackru под названием "Как сопоставить массив, поступающий от объекта сервера, с помощью плагина Knockout Mapping в шаблонах?" (извините, stackru накладывает ограничения на количество ссылок в посте), я пытался играть, используя ответ (jsFiddle: http://jsfiddle.net/ueGAA/1)

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

проблема заключается в том, как viewmodel объявляет ответ, который мне нравится, перенесенный в todo:

var viewModel = 
{
    tasks : ko.mapping.fromJS(data),
    newTaskText: ko.observable(),
    incompleteTasks: ko.computed(function() {     
           return ko.utils.arrayFilter(this.tasks(), function(task) { return !task.isDone() });
    }),
    // Operations
    addTask:  function() {
        alert('Entering add task, count:' + this.tasks().length);
        this.tasks.push(new Task({ title: this.newTaskText() }));
        this.newTaskText("");
    },
    removeTask: function(task) { this.tasks.remove(task) }

}

Суть здесь: внутри объявления ko.computed() это окно ссылки. Нормально, действительно. Правильное поведение можно получить, если я объявлю ko.computed() после переменной vewmodel.

сюда:

viewModel.incompleteTasks=ko.computed(function() {
    return ko.utils.arrayFilter(viewModel.tasks(), function(task) { return !task.isDone() });
});

Мне это не нравится, потому что он статически ссылается на объект viewModel в анонимной функции.
вопрос в том, как изящно объявить незавершенные задачи непосредственно в объявлении viewmodel? jsFiddle здесь http://jsfiddle.net/Yqg8e/

Спасибо

1 ответ

Решение

Переключитесь с использования литерала объекта на функцию конструктора для вашей ViewModel.

function ViewModel() {
    var self = this;

    self.tasks = ko.mapping.fromJS(data);
    self.newTaskText = ko.observable();
    self.incompleteTasks = ko.computed(function() {       
        return ko.utils.arrayFilter(self.tasks(), function(task) { 
            return !task.isDone()
        });
    });
    self.addTask = function() {
       alert('Entering add task, count:' + self.tasks().length);
       self.tasks.push(new Task({ title: self.newTaskText() }));
       self.newTaskText("");
    };
    self.removeTask = function(task) { self.tasks.remove(task) }
}

ko.applyBindings(new ViewModel());​

Обратите внимание также на использование var self = this; который позволяет получить доступ к this контекст даже внутри внутренних анонимных функций.

Этот метод описан в документах Knockout, в разделе " Вычисляемые наблюдаемые" (перейдите к разделу " Управление" этим).

Вот обновленная скрипка: http://jsfiddle.net/Yqg8e/1/

Другие вопросы по тегам