knockoutjs映射嵌套元素不绑定

时间:2015-01-09 00:09:11

标签: javascript knockout.js mapping

基本上从ajax调用中寻找映射json。 我的js

var mapping = {
    create: function(options) {
    return new Person(options.data.id,options.data.name,options.data.surname,options.data.address,options.data.amounts);
    },
    'address': {
        create: function(options) {
            return new Address(options.data.id,options.data.street,options.data.number);
        }
    },
    'Amounts': {
        create: function(options) {
            return new Amount(options.data.id,options.data.price,options.data.iva);
        }
    }    
};

我收到错误:ReferenceError:fullAddress未定义为我的小提琴:http://jsfiddle.net/2coj72yn/1/ 谢谢你的希望。

2 个答案:

答案 0 :(得分:0)

使用$ data前缀

<div data-bind="with:$data.editingPerson">
    id: <input data-bind="value:$data.id"> <br>      
    name: <input data-bind="value:$data.name"> <br>
    surname: <input data-bind="value:$data.surname"> <br>
    Full Name: <input data-bind="value:$data.fullName"> <br>
    Address: <input data-bind="value:$data.fullAddress"> <br>
   <table>...

示例:http://jsfiddle.net/baryon/NsuL7/1/

来源:knockout viewmodel property undefined

答案 1 :(得分:0)

您的代码存在各种问题,但由于映射插件使用不当,因此不会抛出错误。

范围问题

首先,fullAddressAddress个实例的属性,因此您应该在其前面添加address.其次,with绑定告诉Knockout查找editingPerson.savePerson哪个不存在。因此,您必须将绑定更改为根范围,如下所示:click: $root.savePerson

<!-- current --> inputAddress: <input data-bind="value: fullAddress">
<!-- correct --> inputAddress: <input data-bind="value: address.fullAddress">

<!--current --> <button data-bind="click:savePerson" type="button">Save</button>
<!--correct --> <button data-bind="click:$root.savePerson" type="button">Save</button>

还建议使用对象作为构造函数参数,以便更容易与mapping plugin结合使用,并且您是否希望省略一个属性。

映射插件

映射插件文档明确指出:

  

对象的所有属性都转换为可观察

这意味着您不能包含计算 observable并期望它们正常工作。实际上,文档中有一部分关于用计算的observable here扩充JS对象。我可能错了,但是从我的测试和文档来看,映射的create函数可以用于嵌套对象。遵循此文档,您不需要显式创建所有可观察属性,因为对ko.mapping.fromJS的单个调用可以实例化它们。您的新Person构造函数如下所示:

function Person(options){
    // because these arrays contain nested objects with computed observables,
    // they should have a special create function
    var self = this, mapping = {
        'amounts': { create: function(options) { return new Amount(options.data); }},
        'address': { create: function(options) { return new Address(options.data); }}
    };  
    // instantiates all properties, eg. surname, name, id
    ko.mapping.fromJS(options, mapping, this);
    self.fullName   = ko.computed(function() {
        return self.name()+" - "+self.surname();
    });  
}

另一个未成年人&#39;你只能在命名对象属性上使用映射插件的create函数,所以在你的原始小提琴中,插件永远不会找到persons数组,因为它是数据根。

查看this fiddle以获取完整的解决方案。