knockoutjs 映射嵌套元素不具有约束力
knockoutjs mapping nested elements is not binding
基本上是从 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 is not defined 我的小提琴:http://jsfiddle.net/2coj72yn/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
你的代码存在各种问题,但不会因为映射插件使用不当而报错。
作用域问题
首先,fullAddress
是 属性 个 Address
实例,因此您应该在其前面加上 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
结合使用,如果您希望省略一个 属性.
映射插件
映射插件文档明确指出:
All properties of an object are converted into an observable.
这意味着您不能包含 computed observables 并期望它们正常工作。实际上,该文档有一部分是关于使用计算的可观察对象 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();
});
}
另一个小问题'nit-pick':你只能在命名对象属性上使用映射插件的create
函数,所以在你原来的fiddle中,插件永远找不到persons
数组,因为它是数据根。
查看 this fiddle 以获得完整的解决方案。
基本上是从 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 is not defined 我的小提琴:http://jsfiddle.net/2coj72yn/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
你的代码存在各种问题,但不会因为映射插件使用不当而报错。
作用域问题
首先,fullAddress
是 属性 个 Address
实例,因此您应该在其前面加上 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
结合使用,如果您希望省略一个 属性.
映射插件
映射插件文档明确指出:
All properties of an object are converted into an observable.
这意味着您不能包含 computed observables 并期望它们正常工作。实际上,该文档有一部分是关于使用计算的可观察对象 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();
});
}
另一个小问题'nit-pick':你只能在命名对象属性上使用映射插件的create
函数,所以在你原来的fiddle中,插件永远找不到persons
数组,因为它是数据根。
查看 this fiddle 以获得完整的解决方案。