淘汰具有多对多关系的JS ObservableArray
Knockout JS ObservableArray with many-to-many relationships
我正在使用Knockout.js创建一个访客列表应用程序,到目前为止一切进展顺利。然而,我有一个最佳实践问题。我的应用程序有几种不同类型的对象:来宾和标签。客人可以有多个标签,标签可以有多位客人。在应用程序的不同位置,我需要分别显示两个数组。例如,我有一个"访客"视图,可以在其中看到所有访客及其关联的标签,我还有一个"标签"视图,在其中可以看到所有标签及其关联的访客。目前,我为客人添加标签的代码如下:
var tag = function(opts) {
this.guests = ko.observableArray()
// Other tag code here...
}
var guest = function(opts) {
this.tags = ko.observableArray()
// Other guest code here...
var self = this
this.addTag = function(tag) {
self.tags.push(tag)
tag.guests.push(self)
}
}
我知道在Knockout中,除了独立更新每个observableArray之外,一定有更好的方法来实现这种多对多关系。这也导致了一种递归应用程序结构,其中来宾有一个包含标记的标记属性/数组,它有一个包括来宾的来宾属性/数组。。。你明白了。
现在,ViewModel结构是这样的:
- Parent Object
- Guests ObservableArray
- Guest Object
- Tag Object as property of Guest
- Tags ObservableArray
- Tag Object
- Guest Object as property of Tag
所以我想我的问题有两个:1)有没有更好的方法来构建ViewModel以避免递归数组?以及2)如何更好地使用Knockout.js以DRY方式更新我的ViewModel,而不是单独更新标签数组和访客数组?谢谢
可能还有其他方法可以做到这一点,但这种方法在不牺牲适当建模的情况下,重复性非常小。服务器应该不会在生成此格式的数据时出现问题。
这是一把(风格粗糙的)小提琴。请注意,单击标签或访客将更新其下方的选择(默认情况下选择第一个)。
基本上,按id存储关系,并使用computed
数组来表示关联。这是一个基本的视图模型:
var ViewModel = function(guests, tags) {
var self = this;
self.guests = ko.observableArray(
ko.utils.arrayMap(guests, function(i){ return new Guest(i); }
));
self.tags= ko.observableArray(
ko.utils.arrayMap(tags, function(i){ return new Tag(i); }
));
self.selectedGuest = ko.observable(self.guests()[0]);
self.selectedTag = ko.observable(self.tags()[0]);
self.guestTags = ko.computed(function() {
return ko.utils.arrayFilter(self.tags(), function(t) {
return self.selectedGuest().tags().indexOf(t.id()) > -1;
});
});
self.tagGuests = ko.computed(function() {
return ko.utils.arrayFilter(self.guests (), function(g) {
return self.selectedTag().guests().indexOf(g.id()) > -1;
});
});
};
更新
因此,我制作了一个新的fiddle来演示不同类型的映射,但这段代码可以很容易地与上面的视图模型共存;它只是单独展示的。它没有处理选择,而是提供了一个通用的查找,这样任何代码都可以使用它。下面是标签中的HTML(来宾是对称的),以及添加到视图模型中的guestMap
函数。
您将注意到,名称现在是input
,因此您可以更改名称并观察所有绑定保持最新。让我知道你的想法:
<div>Tags
<ul data-bind="foreach: tags">
<li>
<input data-bind="value: name, valueUpdate: 'afterkeydown'" />
</br><span>Tags</span>
<ul data-bind="foreach: guests">
<li><span data-bind="text: $parents[1].guestMap($data).name()"></span></li>
</ul>
</li>
</ul>
</div>
self.guestMap = function(id) {
return ko.utils.arrayFirst(self.guests(), function(g) {
return id == g.id();
});
};
我遇到了同样的问题。显示多对多相关内容。我不得不做"网格"风格的显示,并在其中有一个更新机制
我最终复制了我在后台数据库中的结构。两个项目表,中间有联接表。从三个数组中提取数据,并不断更新"join"数组。下面是测试数据和我的测试。
var items = [{name: "T1",id: 1}, {name: "T2",id: 2}, {name: "T3",id: 3}, {name: "T4",id: 4}];
var cats = [{catname: 'C1', catid: 1}, {catname: 'C2',catid: 2}, {catname: 'C3',catid: 3}, {catname: 'C4',catid: 4}];
var catsItems = [{catid:1,itemid:2},{catid:2,itemid:1},{catid:4,itemid:2},{catid:3,itemid:4},{catid:3,itemid:1},{catid:1,itemid:3},{catid:2,itemid:4}];
加入桌面小提琴
我真的不确定这种方法在处理大量数据时有多有效,但我做了我需要它做的事情。
- 自定义过滤淘汰js observableArray
- KNOCKOUT js observableArray 不起作用
- 淘汰具有多对多关系的JS ObservableArray
- 在 observableArray Knockout JS 中切换值
- Knockout.js 从 observableArray 中提取元素返回 undefined
- 绑定多维敲除js observableArray
- Knockout.js中observableArray中对象中计算属性的奇怪行为
- 如果observableArray数组没有与Knockout JS匹配的索引,如何禁用
- 替换Knockout.js observableArray中的所有元素
- Knockout JS-如何正确绑定observableArray
- 敲除js observableArray中的Join函数
- Knockout js observableArray没有得到更新
- 如何更换'/ & # 39;& # 39; & # 39;inside ObservableArray ?js
- 为什么我的UI不更新后,在一个observableArray在Knockout js中添加一个项目
- knockout.js在填充observableArray时太慢
- 无法在Knockout.js中使用observableArray length更新span
- 当输入字段更新时,如何在knockout.js中更新observableArray项?
- 如何使用Knockout.js在ObservableArray的某个位置添加/插入一个项
- 如何在knockout.js中执行完所有observableArray依赖后执行函数
- Knockout JS:observableArray.splice(0)未克隆数组