使用 Knockout.js:
如果一个项目/对象位于多个位置的视图模型中(相同的确切对象),是否可以将两个项目绑定在一起,以便如果用户在一个位置编辑项目,另一个项目会自动更新为出色地?
示例: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 负责对象之间的同步。这可行,但从架构的角度来看,它并不理想,因为数据在整个视图模型中都是重复的。
解决方案 2:(感谢@Jeff Mercado)
http://jsfiddle.net/jeff1203/rndM9/2/
在这个解决方案中,Foo 和 Poo 数组将只包含被引用对象的 ID。在架构上,我认为这是正确的方法,但它也以更多代码为代价。
如果您正在阅读本文,那么最终您可能会将视图模型发布到服务器进行处理,这可能需要将模型保存回您的数据库。这两种解决方案都能充分处理数据库中存在的一对多关系。在我的要求中,我还使用顺序负数作为 ID 号(ID:-1、ID:-2 等)向 AllMembers 数组添加新元素。服务器端处理顺序应如下所示:
- 创建一个数组以将负 ID 映射到数据库中相应的数据库新创建的 ID
- 循环遍历 AllMembers 数组中的成员并更新/创建数据库中的每个成员。如果创建新成员,请将其负数和新 ID 添加到您在步骤 1 中创建的数组中。
- 删除数据库中 Foo/Poo 之间所有现有的 1 对多关系,因为您的模型现在是该信息的主人
- 循环遍历 Poo 和 Foo,并将模型中到 Foo/Poo 的所有关系添加到 1-many 表中(使用 ID)
呼...
淘汰赛很棒。