我认为我提出问题的方式误导了您,因此我进行了重大编辑。我将使用来自 knockoutjs 教程的代码
“加载和保存数据”,步骤 3
我做了一个改变来表明我的意思。
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) };
// ** Read this!!
// This below is the original code in the tutorial, used to fetch remote data.
// I commented this out, and i will use the below load() method instead.
// **
//$.getJSON("/tasks", function(allData) {
// var mappedTasks = $.map(allData, function(item) { return new Task(item) });
// self.tasks(mappedTasks);
//});
// This is the load method to emulate the above commented
// $.get. Please, DO NOT CARE about the implementation, or
// the setTimeout usage, etc., this method ONLY EXISTS TO
// EMULATE A SLOW SERVER RESPONSE.
// So, we have to ways of using it:
// - load('slow'), will set result after 1 second
// - any other argument will set result instantly.
self.load = function(howFast) {
if (howFast == 'slow') {
setTimeout(function(){
mappedTasks = [];
mappedTasks.push(new Task({
title: 'Some task slowly loaded from server',
isDone: false
}));
}, 1000);
} else {
mappedTasks = [];
mappedTasks.push(new Task({
title: 'Some task quick!',
isDone: false
}));
}
}
// Now please note this:
// - if i use load(), mappedTask is instant updated and
// everything runs fine
// - if i use load('slow'), mappedTask is updated AFTER
// VALUES ARE BOUND, so if you open your browser console
// you will see an "Uncaught ReferenceError: mappedTasks is not defined" error.
self.load();
self.tasks(mappedTasks);
}
ko.applyBindings(new TaskListViewModel());
问题:绑定是在 ViewModel 完成初始化之后应用的,因此会导致错误。我认为我在代码注释中提供了足够的详细信息,请问您是否需要更多详细信息。无论如何,我有点惊讶以前没有人打过这个东西,所以我在这里错过了一些非常重要的东西吗?
问题:如何避免这种情况?