2014-12-05 52 views
0

我已經閱讀了關於knockoutjs的文檔,我明白,單選按鈕使用檢查綁定。這對我來說的問題是綁定工作的方式不適合我的場景。在他們的例子中,一個單選按鈕被分配一個值,當選擇單選按鈕時,它將驗證單選按鈕的值與ko.computed函數中的值,以確定檢查哪個單選按鈕。然而,在我的下面的例子中,我有一個單行按鈕的單選按鈕。如何在選中/單擊單選按鈕時更新KO對象的屬性?

我需要屬性「IsPrimary」更新爲true時,他們選擇一個單選按鈕的行...單選按鈕的名稱是相同的,防止多個選擇。我已經能夠獲取屬性更新爲KO,但它不會更新我的mvc模型中的屬性,也不會檢查單選按鈕以顯示它被選中。

<table data-bind="foreach: details"> 
      <tr> 
       <td> 
        <div> 
         <input data-bind="value: StandardAccountNo, attr: {name: 'NewAccountGroupDetails[' + $index() + '].StandardAccountNo'}" /> 
        </div> 
       </td> 
       <td> 
        <div class="radiobutton"> 
         <input type="radio" data-bind="click: $parent.markPrimary, attr: {value: $index()}" name="primary" /> 
        </div> 
       </td> 
       <td> 
        <a href="#" data-bind="click: $parent.removeDetail">Remove</a> 
       </td> 
      <tr> 
</table> 

<button data-bind="click: addDetail">New</button> 

敲除

var Detail = function() { 
    this.StandardAccountNo = ko.observable(new Date()); 
    this.IsPrimary = ko.observable(false); 
    this.EffectiveDate = ko.observable(formattedDate(new Date())); 
    this.EndDate = ko.observable(formattedDate(new Date())); 
}; 

function ViewModel() { 
    var self = this; 
    var rawList = '@Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model.NewAccountGroupDetails))'; 
    self.details = ko.observableArray(convertJSONToKoObservableObject($.parseJSON(rawList))); 
    self.details.push(new Detail()); 

    self.addDetail = function() { 
     self.details.push(new Detail()); 

     $('.datepicker').each(function (i, obj) { 
      $(obj).datepicker({ changeYear: true, changeMonth: true }); 
     }); 
    } 

    self.markPrimary = function() { 
     console.log(this); 
     this.IsPrimary(true); 
     $('.radiobutton').each(function (i, obj) { 
      console.log(obj); 
     }); 
    } 

    self.removeDetail = function() { 
     self.details.remove(this); 
    } 
} 

ko.applyBindings(new ViewModel()); 

注:console.logs輸出KO對象,表示所選擇的行和其工作原理。下一個只是輸出每一行上有一個單選按鈕,它的工作原理。我試圖用這個來確定如何標記頁面上的單選按鈕,並確保我的mvc模型上的屬性得到更新,以便回發。

+0

你正在接近這個困難的方式。當您使用KO時,您可以輕鬆獲取JavaScript對象,並使用jquery ajax將其發佈到MVC控制器,並使用響應(可以是JSON或HTML)更新當前頁面。但是,如果你想繼續這麼做,可以用一個普通的MVC頁面做好幾行,你會發現''''控件得到了不同的名字,最後包括一個像'[n]'這樣的索引。一旦你瞭解了MVC如何生成這些名字,你可以使用knockout'name:'綁定來模擬它們,以便在發佈到常規MVC操作時可以理解它們。 – JotaBe 2014-12-06 03:38:16

+0

正確,我已經通過ko foreach生成了mvc名稱。這是如何更新mvc模型的回發,而Ko處理頁面客戶端的更新。你能提供一個你所說的方法的例子嗎? – user1732364 2014-12-08 14:31:06

回答

0

試試這個:

self.markPrimary = function (currentDetail) { 
     ko.utils.arrayForEach(self.details(), function (detail) { 
      detail.IsPrimary(false); 
     }); 
     currentDetail.IsPrimary(true); 
     return true; 
} 
+0

這將更新視圖模型,但不是用於回發的mvc模型,因爲單選按鈕的名稱相同,並且不遵循mvc名稱約定。關於如何擴展這個更新我的mvc模型的回帖? – user1732364 2014-12-08 15:09:41

0

我認爲你從視asp.net mvc的點接近這個有點過分。嘗試首先隔離客戶端的問題,然後序列化模型,然後處理您的服務器。

至於淘汰賽而言,這將是如何做你想要什麼:http://jsfiddle.net/z1b3mh89/

// items have names and a computed function that knows whether 
// this item is primary among other items 
function Item(name, primaryObservable) { 
    this.name = name; 
    this.isPrimary = ko.computed(function(){ 
     return this.name === primaryObservable(); 
    }, this); 
} 

(function(){ 
    var i = 0; 
    var viewModel = { 
     primaryItemName: ko.observable(), 
     items: ko.observableArray(), 
     add: function (a,b,c) { 
      this.items.push(new Item(i++ + ' choice', this.primaryItemName)); 
     } 
    }; 

    // add a few items 
    viewModel.add(); 
    viewModel.add(); 
    viewModel.add(); 

    // add a computed that renders a textual representation of the model 
    // just to see the changes live (this is only for DEBUG) 
    viewModel.log = ko.computed(function() { 
     return this.items().map(function (item) { 
      return item.name + (item.isPrimary() ? ' [primary]' : ''); 
     }).join(', '); 
    }, viewModel); 

    ko.applyBindings(viewModel); 
})(); 

和你的HTML很簡單:

<!-- ko foreach: items --> 
<label> 
    <input type="radio" name="group1" data-bind="checked: $parent.primaryItemName, value: name"/> 
    <span data-bind="text: name"/> 
</label> 
<!-- /ko --> 

<h3>The Items in the view model:</h3> 
<p data-bind="text: log"></p> 

<button data-bind="click: add">Add Item</button> 

一旦你得到那個工作,您的視圖模型應始終處於良好狀態。你可以擔心序列化併發送給mvc。