4

将您的 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 - 带有回调的模型和视图模型

   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
          }
       }
    }

优点

  • 数据检索上的更多代码重用(即在一个地方加载 someData)

  • 接近 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 等)会很复杂
4

1 回答 1

3

我个人对自加载虚拟机感到不舒服。因此,我建议先加载数据(模型),然后将其传递给 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 => ViewModel => Model

但是,VM 可以重新加载数据或对用户交互进行异步调用。例如,用户可以单击页面上的按钮再次加载当前时间。这些类型的交互显然会发生在现有的虚拟机内部。但问题与初始负载有关,我以这种方式处理。

于 2012-11-05T20:13:40.200 回答