KnockoutJs映射到查看模型复杂属性

时间:2013-07-18 00:44:54

标签: knockout.js knockout-mapping-plugin

我是新手淘汰并尝试我认为简单的场景,但它只是不起作用。当选择更改时,两个输入都不会更改,并且选择列表不会初始化为selectedFormat。

HTML:

<input type="text" data-bind="value: selectedFormat.id" />
<input type="text" data-bind="enable: selectedFormat.fields()[0].enabled" />

<select data-bind="options: formats, optionsText: 'name', value: selectedFormat" />

JS:

var data = {
    formats: [
        { id: 1, name: 'Format 1', fields: [
            { id: 1, enabled: true }, 
            ]}, 
        { id: 2, name: 'Format 2', fields: [
            { id: 1, enabled: false }, 
            ]}
        ], 
    selectedFormat: 
        { id: 2, name: 'Format 2', fields: [
            { id: 1, enabled: false }, 
            ]}
    }

var vm = ko.mapping.fromJS(data);

ko.applyBindings(vm);

http://jsfiddle.net/paulbau/ZnqNN/1/

1 个答案:

答案 0 :(得分:2)

你几乎在你的小提琴里,所有的部分都在那里,他们只需要连接。

Te映射插件不会为包含复杂对象的属性自动创建可观察对象。因此,默认情况下,映射后selectedFormat将不是可观察的。因为你想要编写value: selectedFormat,所以它必须是可观察的,因此你需要一个使selectedFormat可观察的自定义映射配置:

var mapping = {
    'selectedFormat': {
        create: function(options) {
            return ko.observable(ko.mapping.fromJS(options.data));
        }
    }
}

如果您定义了create函数,那么您负责映射其值,因此您需要使用ko.mapping.fromJS在create函数内调用options.data来映射selectedFormat内的值。 1}}也是可观察的。

然后你需要告诉ko.mapping使用你的映射配置:

var vm = ko.mapping.fromJS(data, mapping);

现在只需更改您的绑定,因为selectedFormat将是一个可观察的,因此您需要使用selectedFormat()获取其值:

<input type="text" data-bind="value: selectedFormat().id" />
<input type="text" data-bind="enable: selectedFormat().fields()[0].enabled" />

演示JSFiddle.

如果您希望初始选择工作,那么您的映射需要按ID查找所选项目,而不是创建新对象:

var mapping = {
    'selectedFormat': {
        create: function(options) {
           var selected = ko.utils.arrayFirst(options.parent.formats(), 
               function(item){
                   return item.id() == options.data.id;
            }); 
            return ko.observable(selected);
        }
    }
}

演示JSFiddle.