2012-03-23 80 views
1

当使用对象作为选择列表值时,我无法使用Knockout选择列表绑定。如果我使用字符串,它工作正常,但我想绑定对象。Knockout.js选择值绑定到对象

我有一个礼物对象,它有一个标题,价格和公司。我有一个公司名单,每家公司都有一个ID和名称。然而,初始选择在选择列表中不正确。

请参阅小提琴:http://jsfiddle.net/mrfunnel/SaepM/

这种结合MVC3视图模型时,对我很重要。虽然我承认这可能是因为我以错误的方式做事。

如果我有以下型号:

public class Company 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 

} 
public class GiftModel 
{ 
    public Company Company { get; set; } 
    public string Title { get; set; } 
    public double Price { get; set; } 
} 

如何选择一个公司,是在绑定我的控制器?我是否需要向GiftModel添加CompanyId属性并绑定到该属性或编写自定义绑定器。我在这里错过了什么?

在此先感谢。

回答

3

你需要做很多东西。

您的ViewModel中的CompanyId是绑定并使其成为可观察对象的唯一方法。 你不能让一个观察的对象只it's值

<form class="giftListEditor" data-bind="submit: save"> 
    <!-- Our other UI elements, including the table and ‘add’ button, go here --> 

    <p>You have asked for <span data-bind="text: gifts().length">&nbsp;</span> gift(s)</p> 
    <table> 
     <tbody data-bind="foreach: gifts"> 
      <tr> 
       <td>Gift name: <input data-bind="value: Title"/></td> 
       <td>Price: $ <input data-bind="value: Price"/></td> 
       <td>Company: <select data-bind="options: $root.companies, optionsText: 'Name', optionsValue: 'Id', value: CompanyId"/></td> 
       <td>CompanyId: <span data-bind="text: CompanyId"></span></td> 
       <td><a href="#" data-bind="click: $root.removeGift">Delete</a></td> 
      </tr> 
     </tbody> 
    </table> 
    <button data-bind="click: addGift">Add Gift</button> 
    <button data-bind="enable: gifts().length > 0" type="submit">Submit</button> 
</form>​ 

模型

// Fake data 
var initialData = [ 
    { Title: ko.observable('Item 1'), Price: ko.observable(56), CompanyId: ko.observable(1) }, 
    { Title: ko.observable('Item 2'), Price: ko.observable(60), CompanyId: ko.observable(2) }, 
    { Title: ko.observable('Item 3'), Price: ko.observable(70), CompanyId: ko.observable(2) } 
]; 

var initialCompanies = [ 
    { Id: 1, Name: "Comp 1" }, 
    { Id: 2, Name: "Comp 2" }, 
    { Id: 3, Name: "Comp 3" } 
]; 

var viewModel = { 
    gifts: ko.observableArray(initialData), 
    companies: initialCompanies, 

    addGift: function() { 
     this.gifts.push({ 
      Title: "", 
      Price: "", 
      Company: { Id: "", Name: "" } 
     }); 
    }, 
    removeGift: function($gift) { 
     viewModel.gifts.remove($gift); 
    }, 
    save: function() { 
     console.log(ko.toJS(viewModel.gifts)); 
    } 
}; 

ko.applyBindings(viewModel, document.body);​ 
+0

谢谢你花时间回答这个问题。我看到这是解决问题的唯一方法。你是冠军。 – TheGwa 2012-05-07 10:35:13

0

使对象观察到,使用foeach结合。如果你有这样一个场景:

var model = { 
    myObj : ko.observable(); 
} 

,如果你尝试绑定到myObj.label它不会工作:

<span><a href="#" data-bind="text: myObj.label"></a></span> 

然而,使用foreach绑定:

<span data-bind="foreach: myObj"><a href="#" data-bind="text: label"></a></span> 

ko以通常javascript方式通过数组的方式迭代属性,事情就会起作用。