将 ajax 调用放在 Knockout ViewModel 中是否明智,还是应该将其放在模型中?我想出了一些方法,但没有一种感觉是完全正确的。
方法 1 - 仅 ViewModel
window.someDataVM = function() {
var self = this;
//used to enable loading indicator
self.pendingLoad = ko.observable(true);
self.myData = ko.observableArray();
self.load = function() {
//make ajax call and populate myData observable array
}
}
优点
- 最简单的代码结构——更易于维护
缺点
- 不重用数据检索
方法 2 - 带回调的模型和 ViewModel
window.someDataVM = function() {
var self = this;
//used to enable loading indicator
self.pendingLoad = ko.observable(true);
self.myData = ko.observableArray();
self.load = function() {
someDataM.load(function(data) {
//populate myData observable array
});
}
}
window.someDataM = function() {
return {
load: function(callback) {
//get data via ajax and return via callback
}
}
}
优势
更多的数据检索代码重用(即一个地方加载一些数据)
接近 3 的更简单的界面
缺点
- 使用回调
方法 3 - 使用 Knockout 模型的模型和 ViewModel
window.someDataVM = function() {
var self = this;
//used to enable loading indicator
self.pendingLoad = ko.observable(true);
self.myData = ko.observableArray();
self.load = function() {
someDataM.load();
}
someDataM.isLoaded.subscribe(function(isLoaded) {
if (isLoaded) {
//populate observable array
}
});
}
window.someDataM = function() {
return {
isLoaded: ko.observable(false);
items: [],
load: function() {
//get some data, populate items, set isLoaded
}
}
}();
优势
- 不使用回调
- 保持数据代码集中
缺点
- 拥有大量数据入口点(即 LoadById、LoadByName 等)会很复杂
最佳答案
我个人不太喜欢自动加载 VM。因此,我建议先加载数据(模型),然后再将其传递给 VM。
从概念上讲,它应该是这样的:
function loadData() {
//load data, can be asynchronously. Then callback
callback(data);
}
function callback(data) {
var vm = new someDataVM(data);
//do something with VM.
ko.applyBindings(vm);
}
当 VM 由其他 VM(多屏应用程序)创建时,这种方法更有意义。此外,这种方法通过建立逻辑依赖链来强调模型- View - View 模型分离:
View => ViewModel => Model
但是,VM 可以重新加载数据或对用户交互进行异步调用。例如用户可以单击页面上的按钮再次加载当前时间。显然,这些类型的交互将发生在现有虚拟机内部。但问题与初始负载有关,我是这样处理的。
关于javascript - 使用 Knockout 时是否应该在模型或 View 模型中加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13239489/