阅读stackoverflow中的这篇题为"如何使用模板中的Knockout Mapping插件映射到来自服务器对象的Array?"的交流(很抱歉stackoverflow限制了我的帖子链接数量)我试着利用这个答案(jsFiddle:http://jsfiddle.net/ueGAA/1)
因此,练习是在learn.klockoutjs.com上制作名为"加载和保存数据"的knockoutjs教程的todo,但使用敲除映射。
问题在于答案的视图模型声明,我喜欢它,这里转换为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.conted()的声明中,this引用了窗口。确实很正常。如果我在vewmodel变量之后声明ko.conted(),就可以获得正确的行为。
这边:
viewModel.incompleteTasks=ko.computed(function() {
return ko.utils.arrayFilter(viewModel.tasks(), function(task) { return !task.isDone() });
});
我不喜欢它,因为它静态地引用了匿名函数中的对象viewModel
问题是:如何以优雅的方式直接在视图模型声明中声明不完整的任务?jsFiddle在这里http://jsfiddle.net/Yqg8e/
感谢
从使用对象文字切换到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文档中的Computed Observables部分进行了描述(跳到标题为管理'This'的部分)。
这是一个更新的小提琴:http://jsfiddle.net/Yqg8e/1/