2012-12-03 17 views
0

我对ko有一个特别棘手的问题。我会试着解释一些例子。Knockoutjs - 新实例VM的复杂对象绑定

首先,这里是我试图渲染的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"} 
    ] 
    } 

那么,有没有什么大的问题就在这里呢。我为每个设备获得一行用户界面。每行都是一个填充了设备类型的类型下拉列表。如果我只是编辑我所拥有的,那么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())); 
}; 

最终它会是不错的applianceType从阵列复制的电器[I] .ApplianceType,但说实话,我只是试图让标识更新有。剩下的我可以在服务器上完成。

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

谢谢大家!

回答

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绑定,以指定选项的显示文本是什么。

1

您的ApplianceType在您的ApplianceViewModel是可观察的。但是你value的选择元件结合是

value: $data.ApplianceType.Id 

你想要得到的观察到的值的Id属性,而不是从可观察本身。你应该绑定的那部分更改为:

value: ApplianceType().Id 

或者也许是更好的选择是让ApplianceType无法观测。您通常应该制定您希望观察可观察到的具体值,而不是其他视图模型。

function ApplianceViewModel(applianceTypeViewModel) { 
    var self = this; 

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