映射和绑定嵌套对象和数组
Mapping and binding nested objects and arrays
我有一个object
,在这个对象中我有个项,其中一个项是array
,它也包含objects
。数据示例如下所示。
我使用敲除将这些数据绑定到视图,所以我认为我需要实现一个双循环,用于返回对象和子数组中的对象,以便能够在视图中绑定它们。
样本数据:
"singers": {
"ijiyt6ih": {
"id": ObjectId('ijiyt6ih'),
"name": "John",
"songs": [
{
"id": ObjectId('okoiu8yi'),
"songName": "Hello There",
"year": "1980"
},
{
"id": ObjectId('sewfd323'),
"songName": "No More",
"year": "1983"
}
]
},
"98usd96w": {
"id": ObjectId('98usd96w'),
"name": "Jack",
"songs": [
{
"id": ObjectId('iew342o3'),
"songName": "Hurry Up",
"year": "1985"
}
]
}
}
我需要找到一种适当循环的方法,这样我就可以修改返回的数据,使用knockout将其绑定到viewModel。
以下是我的viewModel的样子:
singersViewModel = function(data) {
var self = {
singerId: ko.observable(data.id),
singerName: ko.observable(data.name),
songName: ko.observable(...),
songYear: ko.observable(...)
};
我不确定是否必须返回两组不同的数据。
至于循环。我可以循环并返回歌手列表以显示在页面上,但我无法获得每个歌手中显示的歌曲列表。
到目前为止,这是我的循环:
var self = {},
singer,
tempSingers = [];
self.singers = ko.observableArray([]);
for (singer in singers) {
if (singers.hasOwnProperty(singer)) {
tempSingers.push(new singersViewModel(singers[singer]));
}
}
self.singers(tempSingers);
我试图为循环中的歌曲复制相同类型的循环,但使用hasOwnProperty
时会出错,因为歌曲是array
。
在包含的片段中,您可以看到如何将原始数据映射到可以绑定到视图的视图模型。
我将id保留为常规属性,并将名称转换为可观测值,以便对其进行编辑。在底部,您可以看到当前的视图模型状态。
还有一个示例视图,它迭代歌手列表,以及每个歌手中的歌曲列表。
正如您所看到的,我正在使用映射实现解决方案。对于映射,您需要实现一个回调,该回调接收每个原始对象并返回一个具有新结构的新对象。例如,这部分代码
_.map(_singers, function(singer) {
return {
id: singer.id,
name: ko.observable(singer.name),
// ... songs:
})
迭代每个歌手(问题中的样本数据),并为每个歌手创建一个带有id的新对象,一个包含名称的可观察对象(以及歌曲的映射,我在这个片段中没有显示)。
注意:我使用的是lodash,但许多浏览器本机支持将map作为数组函数
var ObjectId = function (id) { return id; }
var singers = {
"ijiyt6ih": {
"id": ObjectId('ijiyt6ih'),
"name": "John",
"songs": [
{
"id": ObjectId('okoiu8yi'),
"songName": "Hello There",
"year": "1980"
},
{
"id": ObjectId('sewfd323'),
"songName": "No More",
"year": "1983"
}
]
},
"98usd96w": {
"id": ObjectId('98usd96w'),
"name": "Jack",
"songs": [
{
"id": ObjectId('iew342o3'),
"songName": "Hurry Up",
"year": "1985"
}
]
}
};
var SingersVm = function(_singers) {
var self = this;
self.singers = _.map(_singers, function(singer) {
return {
id: singer.id,
name: ko.observable(singer.name),
songs: _.map(singer.songs, function(song) {
return {
name: ko.observable(song.songName),
id: song.id
};
})
};
});
return self;
};
var vm = new SingersVm(singers);
//console.log(vm);
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-bind="foreach: singers">
<div>
<input data-bind="value: name"/> (<span data-bind="text: id"></span>)
<ul data-bind="foreach:songs">
<li>
<input data-bind="value: name"/> (<span data-bind="text: id"></span>)
</li>
</ul>
</div>
</div>
<pre data-bind="html: ko.toJSON($root,null,2)">
</pre>
相关文章:
- 将数组对象传递到struts2中的操作类
- 如何使用jquery返回php-json数组对象
- 从其名称获取javascript数组对象
- 值未与数组对象绑定
- 如何按数组/对象值的倍数过滤对象数组
- 在表中显示数组对象
- 在数组对象中分组
- 将第二个或多个数组推送到数组对象 AngularJS 中
- 重新排列 JavaScript 数组/对象
- 键上的javascript数组对象过滤器
- handontable:在不更改数据数组/对象的情况下隐藏某些列
- 用于跟踪购物车可用性的Javascript数组/对象/哈希表
- 重建有角度的java脚本数组对象
- 对JSON数组对象进行排序
- 连接与数组对象相关的文本:方式和位置
- 哪些浏览器和版本支持将常见的类数组对象直接传递到fn.apply()
- 如何使用Handlebars循环数组对象和模板
- 是否可以引用JS数组/对象中的另一个元素
- Javascript中的名称索引-数组/对象
- 数组长度不等于数组对象