使用Knockout.js:
如果某项/对象位于一个 View 模型中的多个位置(相同的对象)中,则两个项目都可能绑定(bind)在一起,因此,如果用户在一个位置编辑该项目,则另一项会自动更新为出色地?
示例:http://jsfiddle.net/77Jc5/1/
var model = {
Foo : [
{
ID: 99,
Title: 'This is item number ninety-nine',
Description: 'This is an item included in more than one object'
},
{
ID: 100,
Title: 'This is item number one-hundred',
Description: 'This is an item included in only one object'
}
],
Poo : [
{
ID: 99,
Title: 'This is item number ninety-nine',
Description: 'This is an item included in more than one object'
}
]
};
在该示例中,当用户在Foo或Poo中编辑Item#99时,我希望两者都进行更改...最好是在用户更改它时(按键事件?)。
解决方案
您的模型应如下所示:
var model = {
AllMembers: [
{ ID: 100, Title: 'This is item number 100' },
{ ID: 776, Title: 'This is item number 776' },
{ ID: 456, Title: 'This is item number 456' },
{ ID: 999, Title: 'This is item number 999' }
],
Foo: [],
Poo: []
};
解决方案1 :(贷方为@Joseph Gabriel)
http://jsfiddle.net/lamarant/hMutz/8/
在此解决方案中,Foo和Poo数组将包含该对象的重复实例。 knockout 负责对象之间的同步。这是可行的,但是从架构的角度来看,这是不理想的,因为在整个 View 模型中数据都是重复的。
解决方案2 :(贷方为@Jeff Mercado)
http://jsfiddle.net/jeff1203/rndM9/2/
在此解决方案中,Foo和Poo数组将仅包含引用对象的ID。从体系结构上讲,我认为这是正确的方法,但这也要付出更多代码的代价。
如果您正在阅读本文,那么最终可能会将 View 模型发布到服务器上进行处理,这很可能需要将模型保存回数据库中。两种解决方案都能充分处理数据库中存在的一对多关系。根据我的要求,我还将使用连续的负数作为ID号(ID:-1,ID:-2等)向AllMembers数组添加新元素。服务器端处理序列应如下所示:
ew ...
knockout 很棒。
最佳答案
理想情况下,同一 View 模型中的任何对象最多只能有一个副本。如果可以帮助您,请重构 View 模型,以便您的对象可以引用包含所有对象的数组/映射,以最大程度地减少复制。然后,您的实际对象仅需要获取引用的对象。
var model = {
_FooRefs: [99, 100],
_PooRefs: [99],
_AllObjects: [
{
ID: 99,
Title: 'This is item number ninety-nine',
Description: 'This is an item included in more than one object'
},
{
ID: 100,
Title: 'This is item number one-hundred',
Description: 'This is an item included in only one object'
}
]
};
function ViewModel(data) {
var self = this;
ko.mapping.fromJS(data, {
_AllObjects: {
key: function (obj) {
return obj.ID;
}
}
}, self);
self.Foo = ko.computed(function () {
var fooRefs = ko.utils.unwrapObservable(self._FooRefs);
return ko.utils.arrayMap(fooRefs, function (id) {
// mappedGet was added to mapping plugin version 2.4.1
return self._AllObjects.mappedGet({ ID: id });
});
});
self.Poo = ko.computed(function () {
var pooRefs = ko.utils.unwrapObservable(self._PooRefs);
return ko.utils.arrayMap(pooRefs, function (id) {
return self._AllObjects.mappedGet({ ID: id });
});
});
}
fiddle
要将对象添加到数组,需要确保对象存在于数组/映射中,然后将对象的键添加到引用数组。要删除项目,请删除引用,并选择删除对象。
如果不这样做,则需要保持重复,则可以使用postbox插件来帮助保持对象同步。如果对象存在于单独的 View 模型中,则这种方法将是最好的。