2014-12-05 77 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。

相关问题