javascript - Knockout.js 在 View 模型中修改具有多个位置的项目(又名 : a 1-many relationship)

标签 javascript mvvm knockout.js

使用 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 数组添加新元素。服务器端处理顺序应该是这样的:

  1. 创建一个数组以将负 ID 映射到数据库中相应的数据库新创建的 ID
  2. 遍历 AllMembers 数组中的成员并更新/创建数据库中的每个成员。如果创建新成员,请将其负数和新 ID 添加到您在步骤 1 中创建的数组中。
  3. 删除数据库中 Foo/Poo 之间所有现有的一对多关系,因为您的模型现在是该信息的主人
  4. 遍历 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/

相关文章:

javascript - 检索导航属性动态 WebAPI

wpf - 将 [VisualStateManager] View 状态绑定(bind)到 MVVM View 模型?

asp.net - 清理 ASP.NET MVC 应用程序中的输入

knockout.js - 选定的选项 ID 和值

javascript - 如何将 firestore 'get' 中的数据加载到变量中?

javascript - 从 Electron 子进程访问 DOM 树

javascript - 我如何使用 JSPDF 忽略 div which style = none

c# - TextBox 并不总是更新

wpf - 绑定(bind)到 CompositeCollection 中的单个元素

javascript - 选择列表上的 KnockoutJs 绑定(bind)问题