2012-11-05 43 views
3

將您的ajax調用放入Knockout ViewModel或將它放置在Model中是明智的嗎?我提出了一些方法,但沒有一種感覺完全正確。如果在使用Knockout時模型或視圖模型中出現數據加載

方法1 - 視圖模型只有

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 - 模型和視圖模型隨着基因敲除模型

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等等)

回答

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

這種方法使得虛擬機時被其他虛擬機(多屏應用)創建更有意義。此外,該方法通過使邏輯相關性的鏈強調模型視圖查看模型分離:

View => ViewModel => Model 

然而,虛擬機可以重新加載數據或進行用戶交互異步調用。例如用戶可以再次點擊加載當前時間的頁面上的按鈕。這種相互作用顯然會在現有的虛擬機內部發生。但問題與初始負載有關,我以這種方式處理。

+0

所以這聽起來像你會推薦方法#2與模型通過回調數據返回。這對我來說很有意義,並將問題分開。 –

+0

不是。您的虛擬機首先進行初始化(使用new運算符創建),然後加載數據以自行填充。我不會這樣做,因爲當你需要創建多個虛擬機時,以及是否彼此依賴,這將難以維護。在我的方法中,數據是從VM外部加載的,因此已初始化的VM已準備好立即使用。爲了更好地理解,當虛擬機準備好但數據仍在加載時,想象它們之間的依賴關係鏈。我認爲這很難管理。換句話說,你的問題不包含這種情況。 – Tengiz

+0

啊 - 我明白你在說什麼,是的,這是有道理的。但是 - 在你的例子中,loadData代碼基本上在全局範圍內。將使用方法2中演示的模型加載方法嗎?然後,在初始化應用程序時,將加載的數據傳遞給VM。 –

相關問題