KnockoutJS 绑定在我的视图模型实际创建之前应用
KnockoutJS bindings are applied before my ViewModel is actually created
我认为我提出问题的方式误导了你,所以我做了一个重大编辑。我将使用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 完成初始化后应用,因此会导致错误。我想我在代码注释中提供了足够的细节,问我你是否认为你需要更多。无论如何,我有点惊讶以前没有人打过这个东西,所以我在这里错过了一些非常重要的东西吗?
问:如何避免这种情况?
小提琴
您有一个 html 错误。
setTimeout 函数尝试以编程方式将所选选项设置为不在列表中的选项。浏览器无法执行此操作,因此选择保留在原处。
http://jsfiddle.net/UD89R/6/
function ViewModel() {
// Setup something.
var self = this;
self.foo = ko.observable();
self.options = ko.observableArray([{id:1, name:'Homer'}, {id:2, name:'Barney'}]);
// Make a lot of async data load, like
// $.get('this', function(){ /* Process data */ });
// $.get('that', anotherHandler);
// $.get('somethingElse', self.someObservable);
// Assume the whole process would take 1 second.
setTimeout(function(){
self.options.push({id: 3, name: 'Grimes'});
self.foo(3);
// Too late! foo has been overriden by the select-options binding,
// so this one will not log 'Grimes' as expected.
console.log('Loading done, check foo value:' + self.foo());
}, 1000);
}
相关文章:
- 从html创建一个指令,该指令按类名应用函数
- 我想在AngularJS应用程序中创建一个输入数字框,用户不应该在该框上键入十进制数字.(一个整数输入框)
- Javascript库创建类似heroku仪表板的应用程序
- 我需要学习Java才能使用phoneGap创建android应用程序吗
- 如何创建背景图像列表'URL,并使用jQuery在单击函数时应用它们
- 创建nw.js+流星桌面应用程序
- Chrome应用程序在全屏中创建新窗口-html元素不是全高的
- 如何创建可从多个应用程序使用的PHP登录web服务
- Ember.js+传单+rails(使用Javascript MVC创建rails应用程序并打开源代码映射)
- RequireJS正在加载angular应用程序,但没有't创建app.controller
- 如何对动态创建的输入框应用自动完成
- 我想在混合移动应用程序中使用Sqlite插件(Cordova)创建一个示例项目
- 如何创建应用程序独立通知服务器
- 如何使用php创建应用程序ID后从Facebook获取用户详细信息
- 如何使用电子(如蒸汽覆盖层)创建应用程序
- AngularJS:你如何创建应用程序范围的变量来更新自己
- 使用现有的交互式地图和文件夹(桌面/网络)在Android Studio上轻松创建应用程序
- 在Android上使用java脚本为多个设备创建应用程序
- 是否可以使用GNU公共许可证为公司创建应用程序?
- Apache cordova ,无法创建应用程序