gpt4 book ai didi

knockout.js - 如何处理 knockout View 模型中的多对多关系

转载 作者:行者123 更新时间:2023-12-04 02:48:05 25 4
gpt4 key购买 nike

我的架构中有 2 个表 Service 和 Employee 之间的多对多关系(一个服务可以由多个员工执行,一个员工可以执行多个服务)
.我使用 ServiceEmployee 联结表来创建这种关系。

我在客户端使用 knockout 。 knockout View 模型是通过来自服务器端 View 模型的 knockout.mapping 插件创建的。在服务器端,我有 3 个 View 模型,它们是:

  • EmployeeModel(包含 ServiceEmployeeModel 列表)
  • ServiceModel(包含 ServiceEmployeeModel 列表)
  • ServiceEmployeeModel(包含ServiceId,EmployeeId)[不能包括Employee和
    服务对象以避免客户端的自引用循环]

  • 现在在客户端我有3个模块:

    员工模块
    function Employee(data)
    {
    var self = this;

    ko.mapping.fromJS(data, {
    "Services": {
    create: function (options) {
    return new serviceEmployee(options.data, options.parent);
    }
    }
    }, self);

    ....
    }

    服务模块
    function Service(data)
    {
    var self = this;

    ko.mapping.fromJS(data, {
    "Employees": {
    create: function (options) {
    return new serviceEmployee(options.data, options.parent);
    }
    }
    }, self);

    ....
    }

    ServiceEmployee 模块
    function (data, parent) 
    {
    var self = this;

    ko.mapping.fromJS(data, self);

    //If parent object has property EmployeeId it means the parent object is Employee
    //object and we will add only related Service (not Employee) in order
    //to avoid self reference loop.
    if (parent.EmployeeId) {
    self.Service = ko.computed(function () {
    if (self.ServiceId()) {
    var services = require("modules/tenant").services();
    if (services) {
    var assignedService;
    ko.utils.arrayFirst(services(), function (service) {
    if (service.ServiceId() === self.ServiceId()) {
    assignedService = service;
    return true;
    }
    });
    return assignedService;
    }
    }
    });
    }

    //If parent object has property ServiceId it means the parent object is Service
    //object and we will add only related Employee (not Service) in order
    //to avoid self reference loop.
    if (parent.ServiceId) {
    self.Employee = ko.computed(function () {
    if (self.EmployeeId()) {
    var staff = require("modules/tenant").staff();
    if (staff) {
    var assignedEmployee;
    ko.utils.arrayFirst(staff(), function (employee) {
    if (employee.EmployeeId() === self.EmployeeId()) {
    assignedEmployee = employee;
    return true;
    }
    });
    return assignedEmployee;
    }
    }
    });
    }
    }

    我使用的方法很有效,但我觉得应该有其他更好的方法来处理这种情况。因为在这种方法中 如果我们将服务分配给员工或员工分配给服务然后我们必须手动更新员工和服务数组,我觉得应该有一些更好的方法,以便 knockout 将为我更新这些数组。

    Computed observable 可能是解决方案,但我无法理解。谁能帮我解决这个问题?

    最佳答案

    解决方案A:

    您可能想试试微风:http://www.breezejs.com/它们不直接支持多对多关系,但是如果您像这样公开 navigaiton 对象:

    Service.Employees // Array of ServiceEmployee
    ServiceEmployee.Employee // Employee
    ServiceEmployee.Service // Service
    Employee.Services // Array of ServiceEmplyee

    Breeze 提供了自动跟踪哪些员工和服务相关的机制,允许您执行以下操作:
    var myEmployeesServices = ko.computed(function () {
    return myEmployee.Services().map(function (a) {
    return a.Service;
    };
    ); // an always up to date array of services related to a specific employee
    var newService = entityManager.createEntity("Service", {})
    //entityManager is a class defined by breeze
    //createEntity is a function provided to create new breeze managed objects
    var newServiceLink = entityManager.createEntity("ServiceEmployee", {
    EmployeeId: myEmployee.Id,
    ServiceId: newService.Id
    }); // creates a new ServiceEmployee object linking myEmployee and newService

    // myEmployeeServices now also contains newService

    如果您想使用微风,您必须阅读其他微风功能,例如加载和保存数据等。

    方案 B:

    您可能想查看 ko.mapping 插件的 ignore 属性,例如:
    function Employee(data)
    {
    var self = this;

    ko.mapping.fromJS(data, {
    "Services": {
    create: function (options) {
    return new serviceEmployee(options.data, options.parent);
    }
    }
    }, self);

    self.ServiceObjects = ko.computed(function () {
    var staff = require("modules/tenant").services();
    return staff().filter(function (a) {
    return self.Services.filter(function (b) {
    return b.ServiceId() == a.ServiceId();
    }).length;
    })
    });
    ....
    }

    function serviceEmployee(data, parent) {
    this.EmployeeId = parent.EmployeeId || data.EmployeeId;
    this.ServiceId = parent.ServiceId || data.ServiceId;
    }

    如果我正确编写了映射部分(不确定是否正确,请在此处查看更多详细信息 http://knockoutjs.com/documentation/plugins-mapping.html),那么当您取消映射员工模型时,映射插件应该忽略您计算的 ServiceObjects

    您还可以通过在 Services 数组中添加和删除对象以响应 ServiceObjects 数组中的更改来添加写入函数以添加到您的数组中。

    解决方案 C:

    看看这个其他解决方案: Knockout JS ObservableArray with many-to-many relationships

    关于knockout.js - 如何处理 knockout View 模型中的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22589633/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com