日期:2014-05-16 浏览次数:20428 次
<h3>Tasks</h3> <form data-bind="submit: addTask"> Add task: <input data-bind="value: newTaskText" placeholder="What needs to be done?" /> <button type="submit">Add</button> </form> <ul data-bind="foreach: tasks, visible: tasks().length > 0"> <li> <input type="checkbox" data-bind="checked: isDone" /> <input data-bind="value: title, disable: isDone" /> <a href="#" data-bind="click: $parent.removeTask">Delete</a> </li> </ul> You have <b data-bind="text: incompleteTasks().length"> </b> incomplete task(s) <span data-bind="visible: incompleteTasks().length == 0"> - it's beer time!</span> <form action="/tasks/saveform" method="post"> <textarea name="tasks" data-bind="value: ko.toJSON(tasks)"></textarea> <input type="hidden" name="tasks" type="hidden" data-bind="value: ko.toJSON(tasks)" /> <button type="submit">Save</button> </form> <button data-bind="click: save">Save</button>
function Task(data) { this.title = ko.observable(data.title); this.isDone = ko.observable(data.isDone); } function TaskListViewModel() { // Data var self = this; self.tasks = ko.observableArray([]); self.newTaskText = ko.observable(); self.incompleteTasks = ko.computed(function() { return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() }); }); // Operations self.addTask = function() { self.tasks.push(new Task({ title: this.newTaskText() })); self.newTaskText(""); }; // self.removeTask = function(task) { self.tasks.remove(task) }; self.removeTask = function(task) { self.tasks.destroy(task) }; // Load initial state from server, convert it to Task instances, then populate self.tasks $.getJSON("/tasks", function(allData) { var mappedTasks = $.map(allData, function(item) { return new Task(item) }); self.tasks(mappedTasks); }); self.save = function() { $.ajax("/tasks", { data: ko.toJSON({ tasks: self.tasks }), type: "post", contentType: "application/json", success: function(result) { alert(result) } }); }; } ko.applyBindings(new TaskListViewModel());