作为一项学习练习,我有一个待办事项清单。在我看来,我想显示按完成分组的项目。下面是我的viewmodel。我将如何实现我想要实现的目标,如何设置计算的observable?
function TodoList(name, items) {
this.name = ko.observable(name === "undefined"? "": name);
this.todoItems = ko.observableArray(typeof (items) !== "undefined" ? items : []);
}
function TodoItem(name,completed) {
this.name = ko.observable(name === "undefined" ? "" : name);
this.completed = ko.observable(completed === "undefined" ? false : completed);
}
function TodoListViewModel() {
var self = this;
self.todoLists = ko.observableArray([
new TodoList("Groceries", [
new TodoItem("Milk", true),
new TodoItem("Bread",false),
new TodoItem("Tissues",false)
]),
new TodoList("Luggage", [
new TodoItem("Hairdryer", false),
new TodoItem("Toothbrush",false)
]),
]);
}
答案 0 :(得分:1)
在TodoList
视图模型中创建计算属性。由于计算机的方法没有任何副作用,因此最好使用ko.pureComputed
:
this.completedItems = ko.pureComputed(function() { /* ... */ }, this);
注意:第二个this
参数将当前this
上下文设置为计算的“所有者”。即:在计算的方法中,this
指的是TodoList
实例。
在computed的方法中,评估todoItems
可观察数组以创建对其值的预订:
var currentItems = this.todoItems();
按completed
过滤项目并返回数组:
return currentItems.filter(function(item) {
return item.completed();
});
现在,每个TodoList
都有一个已完成项目的计算数组。您可以以类似的方式创建未完成项目的列表。
如果您想更进一步,并在列表之间对已完成的项目进行分组,您也可以向ko.pureComputed
添加TodoListViewModel
:
this.allCompletedItems = ko.pureComputed(function() {
return this.todoLists()
.map(function(todoList) { return todoList.completedItems(); })
.reduce(function(result, itemList) { return result.concat(itemList); }, []);
}, this);
所有代码在一起:
function TodoList(name, items) {
this.name = ko.observable(name === "undefined" ? "" : name);
this.todoItems = ko.observableArray(typeof(items) !== "undefined" ? items : []);
this.completedItems = ko.pureComputed(function() {
return this.todoItems()
.filter(function(item) {
return item.completed();
});
}, this);
}
function TodoItem(name, completed) {
this.name = ko.observable(name === "undefined" ? "" : name);
this.completed = ko.observable(completed === "undefined" ? false : completed);
}
function TodoListViewModel() {
this.todoLists = ko.observableArray([
new TodoList("Groceries", [
new TodoItem("Milk", true),
new TodoItem("Bread", false),
new TodoItem("Tissues", false)
]),
new TodoList("Luggage", [
new TodoItem("Hairdryer", false),
new TodoItem("Toothbrush", false)
]),
]);
this.allCompletedItems = ko.pureComputed(function() {
return this.todoLists()
.map(function(todoList) {
return todoList.completedItems();
})
.reduce(function(result, itemList) {
return result.concat(itemList);
}, []);
}, this);
}
答案 1 :(得分:0)
您需要定义计算的observable:
self.completedItems = ko.computed(function() {
return self.todoLists().reduce(function(result, list) {
return result.concat(list.todoItems().filter(function(i) { return i.completed(); }));
}, []);
});
function TodoList(name, items) {
this.name = ko.observable(name === "undefined"? "": name);
this.todoItems = ko.observableArray(typeof (items) !== "undefined" ? items : []);
}
function TodoItem(name,completed) {
this.name = ko.observable(name === "undefined" ? "" : name);
this.completed = ko.observable(completed === "undefined" ? false : completed);
}
function TodoListViewModel() {
var self = this;
self.todoLists = ko.observableArray([
new TodoList("Groceries", [
new TodoItem("Milk", true),
new TodoItem("Bread",false),
new TodoItem("Tissues",false)
]),
new TodoList("Luggage", [
new TodoItem("Hairdryer", true),
new TodoItem("Toothbrush",false)
]),
]);
self.completedItems = ko.computed(function() {
return self.todoLists().reduce(function(result, list) {
return result.concat(list.todoItems().filter(function(i) { return i.completed(); }));
}, []);
});
}
ko.applyBindings(new TodoListViewModel());

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<!-- ko foreach: completedItems -->
<div data-bind="text: name"></div>
<!-- /ko -->
&#13;