Как отобразить на массив, поступающий от объекта сервера с помощью плагина 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/