使用 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 中编辑项目 #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 负责对象之间的同步。这可行,但从架构的 Angular 来看,它并不理想,因为数据在整个 View 模型中都是重复的。
解决方案 2:(归功于@Jeff Mercado)
http://jsfiddle.net/jeff1203/rndM9/2/
在此解决方案中,Foo 和 Poo 数组将仅包含引用对象的 ID。在架构上,我认为这是正确的方法,但它也以更多代码为代价。
如果您正在阅读本文,那么在一天结束时您可能会将 View 模型发布到服务器进行处理,这可能需要将模型保存回您的数据库。这两种解决方案都可以充分处理数据库中存在的一对多关系。根据我的要求,我还使用顺序负数作为 ID 号(ID:-1、ID:-2 等)向 AllMembers 数组添加新元素。服务器端处理顺序应该是这样的:
- 创建一个数组以将负 ID 映射到数据库中相应的数据库新创建的 ID
- 遍历 AllMembers 数组中的成员并更新/创建数据库中的每个成员。如果创建新成员,请将其负数和新 ID 添加到您在步骤 1 中创建的数组中。
- 删除数据库中 Foo/Poo 之间所有现有的一对多关系,因为您的模型现在是该信息的主人
- 遍历 Poo 和 Foo,并将模型中与 Foo/Poo 的所有关系添加到一对多表(使用 ID)
呼...
knockout 很棒。
最佳答案
要记住的主要事情是,knockout 将更新它绑定(bind)到的任何对象,但为了使同一个对象可更新并反射(reflect)多个位置的变化,它确实必须是 相同的对象,而不仅仅是克隆。
两个具有相同名称和/或属性的对象是不够的。它实际上必须是单个对象,指向相同的内存地址,然后可以在多个位置显示和绑定(bind)。
我会考虑将您的数据与您的 viewModel 分开,以便您可以根据需要从尽可能多的地方引用同一项目。
var items = [{
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'
}];
var model = {
Foo : [
items[0],
items[1]
],
Poo : [
items[0]
]
};
var viewModel = ko.mapping.fromJS(model);
ko.applyBindings(viewModel);
也就是说,直接在您的 View 模型中使用重复引用似乎有些尴尬。我不知道你的情况是什么,但是否可以使用 Ko.计算给你“poo”值,反之亦然?
关于javascript - Knockout.js 在 View 模型中修改具有多个位置的项目(又名 : a 1-many relationship),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16137887/