2014-01-17 76 views
0

我正在嘗試解決如何將多個模型從主模型綁定到HTML標記的不同部分。 HTML部分是: -在KnockoutJs中綁定多個視圖模型

<ul data-bind="foreach: { data: members}"> 
     <li> 
      <span data-bind="text: MemberId"></span> 
      <span data-bind="text: Name"></span> 
      <span data-bind="text: SwagCompany"></span> 
      <span data-bind="text: SwagThing"></span> 
     </li> 
    </ul> 

<span data-bind="text: winner.Name"></span> 

但無法工作,如何綁定winner.Name,我的模型是這樣的: -

var masterViewModel = { 
    vmA : { ...}, 
    vmB : { ... } 
} 

ko.applyBindings({ 
     winner: ko.observable(masterViewModel.vmB), 
     members: ko.observableArray(mappedData), 
     ... 
    } 

顯然我誤解如何正確applyBindings。我有以下的代碼作爲plunker呈現出什麼,我試圖做一個例子: -

<script> 
$(function() { 

    var masterViewModel = { 
     vmA: function memberViewModel(data) { 
      this.Id = data.MemberId; 
      this.MemberId = ko.observable(data.MemberId); 
      this.Name = ko.observable(data.Name); 
      this.SwagCompany = ko.observable(""); 
      this.SwagThing = ko.observable(""); 
      this.Photo = ko.observable(data.Photo); 
     }, 
     vmB: { 
      Name: "Initial winner..." 
     } 
    }; 

    $.getJSON("/home/memberlist") 
     .then(function (rawData) { 
      return ko.utils.arrayMap(rawData, function (instanceData) { 
       return new masterViewModel.vmA(instanceData); 
      }); 
     }) 
     .done(function (mappedData) { 
      doit(mappedData); 
     }); 

    function doit(mappedData) { 
     ko.applyBindings({ 
      winner: ko.observable(masterViewModel.vmB), 
      members: ko.observableArray(mappedData), 
      getNextWinner: function() { 
       var members = this.members(); 
       var winner = this.winner(); 
       //console.log(ddd.Name()); 
       $.getJSON("/home/nextwinner") 
        .then(function (rawData) { 
         var nextWinner = ko.utils.arrayFirst(members, function (member) { 
          return member.Id === rawData.Winner.MemberId; 
         }); 
         nextWinner.SwagThing(rawData.WonSwag.Thing); 
         nextWinner.SwagCompany(rawData.WonSwag.Company); 
         winner.Name(rawData.Winner.Name); 
        }); 
      } 
     }); 
    } 
}); 
</script> 
+0

我同意@ xdumaine的回答。如果您正確應用MVVM模式,則只需創建並綁定視圖模型一次。與其試圖通過重新綁定到新視圖模型實例來更改頁面內容,您應該能夠簡單地修改加載頁面時綁定的視圖模型實例。 –

回答

4

你的代碼是很混亂的,因爲你要創建一個視圖模型對象中的applybindings打電話,創建視圖模型對象直。使用構造函數語法,並創建視圖模型的新實例。您需要爲applyBindings執行的操作是爲您的主視圖模型指定一個實例。

this JSFiddle爲例,儘量保持代碼的結構和組織性,否則會非常快速地變得非常混亂。

// this is like a constructor for your members 
var memberViewModel = function memberViewModel(data) { 
    var self = this; 
    self.Id = data.MemberId; 
    self.MemberId = ko.observable(data.MemberId); 
    self.Name = ko.observable(data.Name); 
}; 

// This is like a constructor for your master view model 
var masterViewModel = function() { 
    var self = this; 
    self.Members = ko.observableArray(); 

    // put two members into Members 
    self.Members.push(new memberViewModel({MemberId: 1, Name: 'Member1'})); 
    self.Members.push(new memberViewModel({MemberId: 2, Name: 'Member2'})); 

    // set the winner to the first one for default, if you want 
    self.Winner = ko.observable(self.Members()[0]); 

    //do your ajax in this function 
    self.GetNextWinner = function() { 
    self.Winner(self.Members()[1]); 
    } 
}; 

//Apply bindings gets one instance of your view model 
ko.applyBindings(new masterViewModel()); 
+0

偉大的,一個簡單的問題,如果贏家被分成幾個屬性,你會介紹第二個視圖模型,或者你會做一些像'self.Winner' ...'Self.WinnerSwag' ...'self.WinnerSwagThing'然後在'GetNextWinner'函數手動設置每一個? – Rippo

+0

例如http://plnkr.co/edit/EwhMaORuOSsAXhfJMnsj?p=preview – Rippo

+0

@Rippo如果我理解正確,它確實沒關係,你可以將它們保留在主視圖模型上,或者將它們分割成單獨的對象。我傾向於說,將它們保留在主視圖模型中,除非它們都是單個對象實體的一部分。看起來這些屬性實際上是用於UI顯示/操作,在這種情況下,它們應該放在主視圖模型中。 – xdumaine