0

在 stackoverflow 中阅读这篇题为“如何使用模板中的 Knockout Mapping 插件映射到来自服务器对象的数组?”的交流。(抱歉,stackoverflow 限制了帖子的链接数量)我尝试使用答案(jsFiddle:http: //jsfiddle.net/ueGAA/1

所以练习是在 learn.knockoutjs.com 上制作名为“加载和保存数据”的 knockoutjs 教程的待办事项,但使用了敲除映射。

问题在于答案的视图模型声明类型,我喜欢,这里转换为待办事项:

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() 的声明中,是引用window。确实正常。如果我在 vewmodel 变量之后声明 ko.computed() ,可以获得正确的行为。

这边走:

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

我不喜欢它,因为它在匿名函数中静态引用对象 viewModel。
问题是:如何在视图模型声明中以优雅的方式直接声明不完整任务?jsFiddle 在这里http://jsfiddle.net/Yqg8e/

谢谢

4

1 回答 1

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;which 的使用允许访问this上下文,即使在内部匿名函数中也是如此。

这种技术在 Knockout 文档的Computed Observables部分中进行了描述(跳到标题为“管理”的部分)。

这是一个更新的小提琴:http: //jsfiddle.net/Yqg8e/1/

于 2012-09-02T13:29:00.360 回答