2

我花了最近幾天研究以下KnockoutJS問題。knockoutjs從一個函數保存多個viewmodels?

我有一個包含3個viewmodels的頁面。我使用的div id爲公司指定的綁定即:

ko.applyBindings(new viewModel(datasource), $("#sectionQualifications")[0]); 

我也使用RequireJS這真的幫助有讓我的應用程序模塊化,當然是有KnockoutJS效果很好。

我的問題涉及在我的網頁上有(如上所述)3個viewmodels ..沒有重疊,但每個viewmodel有一個SAVE功能。因此,一個快速瀏覽一下視圖模型片段之一:

function viewModel(data) { 
     self = this; 

     self.quals = ko.observableArray(data), 

     self.addQual = function() { 
      self.quals.push(new qualification()); 
     }, 

     self.remove = function (item) { 

      // Remove from the database IF we have an actual record in our viewmodel 
      if (item.Id !== 0) { 
       dataservice_qualifications.deleteEntity(item.Id, ko.toJSON(item), 
        { 
         success: function (ret) { 
          common.notifyOK('Qualification removed'); 
         }, 
         error: function (err) { 
          common.notifyError('Cannot remove that qualification'); 
          console.log('Qualification Remove Error', err); 
          console.log('Remove error object', this.Id); 
         } 
        } 
       ); 
      } 

      // Remove from the actual view model 
      self.quals.remove(item); 
     } 

     // Save and move on.. we need to iterate through the qualifications, update any existing rows (ID NOT 0) or 
     // add new entries (ID IS 0) 
     self.save = function() { 

      var saveData = ko.toJS(this.quals); 
      for (var i in saveData) { 

       // New qualification entry 
       if (saveData[i].Id === 0) { // New qualification entry 
        dataservice_qualifications.postEntity(ko.toJSON(saveData[i]), 
         { 
          success: function (ret) { 
          }, 
          error: function (error) { 
           common.notifyError('Cannot add qualification ' + saveData[i].qualificationName); 
           console.log('Qualification add error', error); 
          } 
         } 
        ); 
       } // eof NEW qualification 

       if (saveData[i].Id > 0) { 
        dataservice_qualifications.putEntity(saveData[i].Id, ko.toJSON(saveData[i]), 
         { 
          success: function (ret) { 
          }, 
          error: function (error) { 
           common.notifyError('Cannot update qualification ' + saveData[i].qualificationName); 
           console.log('UPDATED: ERROR:', error); 
          } 
         } 
        ); 
       } // eof UPDATED qualification 

      } // eof saveData loop 

      common.notifyOK('Qualifications updated'); 

     } // eof savenext function 

     return; 
    }; 

於是從上面的例子,我將有另外2周的ViewModels是相似的,其具有與上述保存功能。所以當然我想用jQuery來說明點擊一個按鈕並保存所有3個視圖模型(即通過每個的SAVE函數)。

因爲我使用RequireJS,我試圖揭露「公共」功能,又試圖在內部調用viewModel.save()函數在這個片段如下:

function saveModel() { 
    viewModel.save(); 

} 

// PUBLIC INTERFACE 
return { 
    saveModel: saveModel, 
    loadViewModel: koMapData 
} 

所以理論我可以從哪個應該觸發viewmodels保存的地方調用「saveModel」函數?

任何幫助真的很感激。順便說一句我已經倒想創建視圖模型的路徑:

var viewModel = { 

    save: function() { 
     blah blah... 
    } 
} 

但是沒有真正的運氣,要麼?我確信我錯過了一些簡單的東西,因爲我認爲你可以/應該能夠以某種方式在外部從視圖模型觸發一個函數?

編輯 僅供參考,模特不重疊..提前

謝謝, 大衛。

+0

您覺得此回答有用嗎? – XGreen

回答

0

其實感謝@XGreen爲你的建議,我可以看到,運作良好,但我使用requirejs,所以我的應用程序結構ISN這絕對不是一場比賽。

不過,我已經成功地在下述溶液:

首先,我創建了一個稍微不同的方式視圖模型..

var viewModel = { 
    quals: ko.observableArray([]), 

    addQual: function() { 
    viewModel.quals.push(new qualification()); 
    }, 

    remove: function (item) { 
    // Do the remove bit.. 
    }, 

    save: function() { 
    var saveData = ko.toJS(viewModel.quals); 
    // Do the save stuff.. 
    } // eof savenext function 

}; // eof viewModel def 

所以視圖模型的定義,然後我有一個輔助函數訪問視圖模型的SAVE功能:

// Private: Allows external access to save the viewmodel 
var viewModelFunctions = { 
    saveModel: function() { 
     viewModel.save(); 
    } 
} 

..然後最後,因爲我使用的是requirejs結構中透露出模塊模式,我創建了一個公共接口函數如下:

function koMapData(incomingData) { 
    datasource = (incomingData === null) ? [new qualification()] : incomingData; 
    viewModel.quals = ko.observableArray(ko.toJS(datasource)); 
    ko.applyBindings(viewModel, $("#sectionQualifications")[0]); 
} 

// PUBLIC INTERFACE 
return { 
    viewModelFunctions: viewModelFunctions, 
    loadViewModel: koMapData 
} 

所以你可以看到與viewModelFunctions的最後一部分,這意味着在另一個模塊(或其它地方)我可以引用/遠程地觸發SAVE功能:

mymodule.viewModelFunctions.saveModel() 

這也意味着(在我的情況下,因爲我有3周的ViewModels我需要從一個事件觸發保存爲)我可以具有靈活性節省時間/我想如何。很顯然,將錯誤等返回給調用模塊是很好的,但原則上它對我來說是如何工作的。

2

你可以像這樣的對象合併視圖模型:

var mainVModel = { 
    vModel1: { // has save method}, 
    vModel2: { // has save method}, 
    saveAll : function(){ 
     mainVModel.vModel1.save(); 
     mainVModel.vModel2.save(); 
    } 
} 

ko.applyBindings(new mainVModel());