【问题标题】:knockoutjs mapping nested elements is not bindingknockoutjs 映射嵌套元素未绑定
【发布时间】:2015-03-07 06:11:15
【问题描述】:

基本上是从 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/ 谢谢你的希望。

【问题讨论】:

    标签: javascript knockout.js mapping


    【解决方案1】:

    使用 $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

    【讨论】:

      【解决方案2】:

      您的代码存在各种问题,但不会因为映射插件使用不当而引发错误。

      范围问题

      首先,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 结合使用,如果您希望省略一个属性。

      映射插件

      映射插件文档明确指出:

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

      这意味着你不能包含 computed observables 并期望它们正常工作。事实上,文档中有一部分是关于用计算的 observables 扩充 JS 对象here。我可能错了,但从我的测试和文档来看,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();
          });  
      }
      

      另一个次要的“挑剔”:您只能在命名对象属性上使用映射插件的 create 函数,因此在您原来的小提琴中,插件将永远找不到 persons 数组,因为它是数据根。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-14
        • 1970-01-01
        • 2020-11-16
        • 2017-03-26
        • 2012-09-07
        • 2012-02-23
        • 1970-01-01
        • 2012-06-07
        相关资源
        最近更新 更多