我正在使用KnockOut映射fromJS从JSON对象创建我的View Model,如下所示:
{
"cats": [{
"name": "fluffy",
"color": "brown",
"kittens": [{
"name": "spot",
"color": "brown"
}, {
"name": "rascal",
"color": "grey"
}, {
"name": "trouble",
"color": "white"
}]
}, {
"name": "kitty",
"color": "red",
"kittens": [{
"name": "lady",
"color": "red"
}, {
"name": "skat",
"color": "striped"
}]
}]
}
HTML:
<div data-bind="foreach:cats">
<span data-bind="text:name"></span>
<table>
<tr data-bind="foreach: kittens">
<td data-bind="text:name"></td>
<td data-bind="text:color"></td>
<td><a data-bind="click: $parent:showParentColor" href="#">Parent Color</a></td>
</tr>
</table>
</div>
使用Javascript:
var KittenModel = function (data) {
ko.mapping.fromJS(data, {}, this);
// ... various computed values added to this
}
var mapping = {
'kittens': {
create: function(options) {
return new KittenModel(options.data);
}
},
'otherItem': {
create: function(options) {
return ('otherStuff');
}
}
}
var data = { ... }; // the JSON above
var CatsViewModel = ko.mapping.fromJS(data, mapping);
问题:
在哪里以及如何放置showParentColor()函数以便数据绑定在小猫表中工作?例如:
function showParentColor(cat) {
alert(cat.color);
}
谢谢!
答案 0 :(得分:3)
您可以根据视图模型层次结构使用以下其中一项:
$ parents array:这是一个包含所有视图模型的数组。
$ parents [0]:父视图模型上下文。(也与$parent
相同)
$ parents [1]:第二个父视图模型上下文。(祖父母)
$ parents [2]:第三个父视图模型上下文。 (曾祖父母)
更新:
如果要在CatsViewModel
级别添加函数,只需将函数添加到创建的模型中。
示例:https://jsfiddle.net/kyr6w2x3/87/
JS:
CatsViewModel.showParentColor = function(item){
console.log(item.name());
console.log(item.color());
}
查看:
<a data-bind="click: $parents[1].showParentColor">
以下是模型的层次结构
- CatsViewModel
- cats : observableArray
- name : observable
- color : observable
- kittens : observableArray
- name : observable
- color : observable
- showParentColor : function
<小时/> 替代方案:您可以自己完成工作并创建模型。根据您的需要,您可以更轻松地进行修改和维护。您还可以在任何您想要的模型中添加
click
功能。
示例:http://jsfiddle.net/kyr6w2x3/91/
HTML:
<div data-bind="foreach:cats">
<span data-bind="text:name"></span>
<table>
<tbody data-bind="foreach: kittens">
<tr>
<td data-bind="text:name"></td>
<td data-bind="text:color"></td>
<td><a data-bind="click: $parent.showParentColor" href="#">Parent Color</a></td>
</tr>
</tbody>
</table>
</div>
<强> JS:强>
var data = {
"cats": [{
"name": "fluffy",
"color": "brown",
"kittens": [{
"name": "spot",
"color": "brown"
}, {
"name": "rascal",
"color": "grey"
}, {
"name": "trouble",
"color": "white"
}]
}, {
"name": "kitty",
"color": "red",
"kittens": [{
"name": "lady",
"color": "red"
}, {
"name": "skat",
"color": "striped"
}]
}]
}
var CatsViewModel = function (data){
var self = this;
self.cats = ko.observableArray($.map(data.cats, function (item) {
return new CatItemViewModel(item);
}));
}
var CatItemViewModel = function (data){
var self = this;
self.name = ko.observable(data.name);
self.color = ko.observable(data.color);
self.kittens = ko.observableArray($.map(data.kittens, function (item) {
var newData = Object.assign({}, item, { parent: self.name()});
return new KittenModel(newData);
}));
self.showParentColor = function (item){
console.log("Parent Name: " , self.name());
console.log("Name: " , item.name());
console.log("Color: " , item.color());
}
}
var KittenModel = function (data) {
var self = this;
self.name = ko.observable(data.name);
self.color = ko.observable(data.color);
self.parent = ko.observable(data.parent);
}
var vm = new CatsViewModel(data);
ko.applyBindings(vm);
答案 1 :(得分:1)
注意:我更喜欢其他答案的方法,但是为了有多种选择,我想提出另一种解决方案。
你可以创建一个&#34;静态&#34; mycpp.dll
中记录其已通过的任何猫咪颜色的方法:
KittenModel
现在,因为您的视图可以访问父子结构,所以您可以使用您想要的任何父级调用此方法:
var KittenModel = function (data) {
ko.mapping.fromJS(data, {}, this);
};
KittenModel.logCatColor = function(cat) {
console.log(cat.color);
};
一个例子:
<!-- to log the parent's color -->
<div data-bind="click: logCatColor.bind(null, $parent)"></div>
<!-- knockout automatically passes `$data` as a first argument,
so you won't need to bind the method to log your own color -->
<div data-bind="click: logCatColor"></div>
&#13;
ko.applyBindings({
name: "parent",
child: {
name: "child",
logName: function(entity) {
console.log(entity.name);
}
}
});
&#13;
在您作为选项传递的工厂功能中,您同时拥有<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h1 data-bind="text: name"></h1>
<div data-bind="with: child" style="border: 1px solid black">
<h2 data-bind="text: name">
</h2>
<button data-bind="click: logName">
log my name
</button>
<button data-bind="click: logName.bind(null, $parent)">
log my parent's name
</button>
</div>
和data
:parent
包含当前正在映射的项目。在这种情况下,options.data
将引用父options.parent
。我还没有测试过这个,但这可能有用:
cat