Knockoutjs - 新实例VM的复杂对象绑定

时间:2012-12-03 19:51:50

标签: knockout.js

我对ko有一个特别棘手的问题。我会尝试解释一些例子。

首先,这是我要渲染的html垃圾。 foreach变量“Appliances”是一个数组,是viewModel的一个属性。选项数据也是视图模型的属性数组。这里的名称是ApplianceTypes。

 <table>   
 <tbody data-bind="foreach: Appliances">
        <tr>
             <td>
                  <select data-bind="options: $root.ApplianceTypes, value: $data.ApplianceType.Id, optionsValue: 'Id', optionsText: 'ApplianceTypeDesc'">
                  </select>
             </td>
             <td>
                  <input data-bind="value: UnitNumber" />
             </td>                
        </tr>
 </tbody>
 </table>

好的,现在我们考虑到了这一点,这里的数据可以更好地填补想法:

 var viewModel = {
    RequestNumber:37,
    UnitNumber:3,
    Appliances:[{
        Id:2,
        ApplianceType:{Id:5, ApplianceTypeDesc:"Water Heating Tankless"},
        ServiceApplianceQuantity:"1",
    }],
    ApplianceTypes:[
        {Id:5, ApplianceTypeDesc:"Water Heating Tankless"},
        {Id:1, ApplianceTypeDesc:"Dryer"},
        {Id:2, ApplianceTypeDesc:"Range"},
        {Id:3, ApplianceTypeDesc:"Heating"},
        {Id:4, ApplianceTypeDesc:"Water Heating"},
        {Id:6, ApplianceTypeDesc:"Fireplace"},
        {Id:7, ApplianceTypeDesc:"Make Up Air Heating"},
        {Id:8, ApplianceTypeDesc:"BBQ"}
    ]
    }

所以,这里没有大问题。我为每个设备获得了一行的UI。每行都是填充了设备类型的类型下拉列表。如果我只是编辑我所拥有的内容,那么viewModel.Appliances [i] .ApplianceType.Id会更新并且生活也很好。如果我尝试向我的设备数组添加新内容,则不会更新applianceType.Id。这是代码:

function ApplianceTypeViewModel() {
var self = this;
self.Id = ko.observable("5");
self.ApplianceTypeDesc = ko.observable("");
};

function ApplianceViewModel(applianceType) {
    var self = this;
    self.Id = ko.observable("-1");
    self.ApplianceType = ko.observable(applianceType);
    self.ServiceApplianceQuantity:"1"
};

viewModel.AddAppliance = function () {
    viewModel.Appliances.push(new ApplianceViewModel(new ApplianceTypeViewModel()));
};

最终通过Appliances [i] .ApplianceType从阵列中复制applianceType会很好,但说实话,我只是想让Id在那里更新。我可以在服务器上做其余的事情。

如果数据存在,则每次都会更改。当我创建它时(使用AddAppliance),数据不会改变。

谢谢大家!

2 个答案:

答案 0 :(得分:1)

ApplianceType中的ApplianceViewModel是可观察的。但是,您对select元素的value绑定是

value: $data.ApplianceType.Id

您希望获得observable值的Id属性,而不是来自observable本身。您应该将绑定的该部分更改为:

value: ApplianceType().Id

或许更好的选择是使ApplianceType不可观察。您通常应该创建要观察可观察值的特定值,而不是其他视图模型。

function ApplianceViewModel(applianceTypeViewModel) {
    var self = this;

    // ...
    self.ApplianceType = applianceTypeViewModel; // just assign the view model
};

答案 1 :(得分:1)

只需在数据绑定中删除“Id”部分,您的Appliances[i].ApplianceType将正确填充所选的设备类型。

value: $data.ApplianceType.Id应为value: $data.ApplianceType

查看此jsfiddle,了解value绑定如何工作的示例http://jsfiddle.net/angelyordanov/gRxMq/

您的代码已修改为http://jsfiddle.net/angelyordanov/vvGgD/

设计淘汰赛的方式options可以是任意javascript对象的数组,而不仅仅是字符串,所选项(value)将是其中一个对象。这就是为什么你有optionsText绑定,以指定选项的显示文本。