javascript - 使用 Knockout 时是否应该在模型或 View 模型中加载数据

标签 javascript mvvm knockout.js

将 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/

相关文章:

javascript - 尝试 Catch 函数不返回值

swift - 用于表单验证的信号和观察者(Reactive Swift)未按预期工作

javascript - 单击外部 Via knockout 绑定(bind)处理程序,从 bootstrap 3.3.6 关闭 knockout Popover

javascript - Knockout - 如何用新值重置动态可观察数组

javascript - AngularJS 中带有验证和 "Show password"选项的密码字段

javascript - 如何使javascript中的弹出窗口只显示一次?

javascript - 在 Firefox 中对 selenium Xpath 路径进行原型(prototype)设计

wpf - 将 ContentControl 绑定(bind)到 WPF 中的深层路径

c# - 通过标记扩展注入(inject)命令是一种好习惯吗?

javascript - 无法让最简单的 knockout.js 示例工作?