Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当使用敲除时,数据加载应该发生在model或viewmodel中吗_Javascript_Mvvm_Knockout.js - Fatal编程技术网

Javascript 当使用敲除时,数据加载应该发生在model或viewmodel中吗

Javascript 当使用敲除时,数据加载应该发生在model或viewmodel中吗,javascript,mvvm,knockout.js,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.observabl

将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
          }
       }
    }
优势

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

  • 更简单的接口方法3

缺点

  • 使用回调
方法3-模型和带淘汰模型的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

从概念上讲,应该是这样的:

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

但是,虚拟机可以重新加载数据或对用户交互进行异步调用。e、 g.用户可以单击页面上的按钮,再次加载当前时间。显然,这些类型的交互将发生在现有vm内部。但问题与初始加载有关,我采用这种方法。

因此,您建议使用方法2,模型通过回调返回数据。这对我来说是有意义的,并将关注点分开。不是真的。您的VM首先初始化(使用新操作符创建),然后加载数据以填充自身。我不会这样做,因为当您需要创建多个vm,并且它们相互依赖时,这将很难维护。在我的方法中,数据是从VM外部加载的,因此初始化的VM可以立即使用。为了更好地跟进,想象一下当所有虚拟机都准备就绪但数据仍在加载时,虚拟机之间的依赖链。我认为这很难管理。换句话说,你的问题不包含这个案例。啊-我明白你的意思,是的,这是有道理的。然而,在您的示例中,loadData代码基本上是全局范围的。使用方法2中演示的模型荷载方法是否可行?然后在初始化应用程序时,将加载的数据传递到VM中。是的,这正是我试图用我的示例表达的:首先准备模型/数据,然后通过向VM传递数据来初始化VM。