0

I have a particularly tricky problem with ko. I'll try to explain around some example stuff.

First, here's the html junk I'm trying to render to. The foreach variable "Appliances" is an array and is a property of the viewModel. The option data is also a property array of the view model. The name of that here is 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>

Ok, so now that we have that in mind, here's the data to fill out ideas a bit better:

 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"}
    ]
    }

So, there's no big problem here yet. I get a UI with a row for each appliance. Each row is a type dropdown filled with appliance types. If I'm just editing what I have, viewModel.Appliances[i].ApplianceType.Id updates and life is good. If I try to add new to my appliances array, the applianceType.Id doesn't get updated. Here's the code for that:

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()));
};

Ultimately it would be nice to have the applianceType copied from the array over the Appliances[i].ApplianceType, but honestly, I'm just trying to get the Id to update there. The rest I can do on the server.

If the data exists, it will change everytime. When I create it new (with AddAppliance), the data will not change.

Thanks Everyone!

4

2 回答 2

1

ApplianceType在你ApplianceViewModel是一个可观察的。但是,您value对 select 元素的绑定是

value: $data.ApplianceType.Id

您想获取Idobservable 值的属性,而不是从 observable 本身。您应该将绑定的那部分更改为:

value: ApplianceType().Id

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

function ApplianceViewModel(applianceTypeViewModel) {
    var self = this;

    // ...
    self.ApplianceType = applianceTypeViewModel; // just assign the view model
};
于 2012-12-03T20:32:41.317 回答
1

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

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

value检查此 jsfiddle 以获取有关绑定如何工作的示例http://jsfiddle.net/angelyordanov/gRxMq/

并且您的代码已修改为可以在这里工作http://jsfiddle.net/angelyordanov/vvGgD/

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

于 2012-12-04T09:13:06.670 回答