Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/asp.net-mvc-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Knockout.js 如何处理淘汰视图模型中的多对多关系_Knockout.js - Fatal编程技术网

Knockout.js 如何处理淘汰视图模型中的多对多关系

Knockout.js 如何处理淘汰视图模型中的多对多关系,knockout.js,Knockout.js,在我的模式中,两个表Service和Employee之间存在多对多关系(一个服务可以由多个员工执行,一个员工可以执行多个服务) . 我使用ServiceEmployee连接表来创建此关系 我在客户端使用knockout。knockout viewmodels是通过服务器端viewmodel中的knockout.mapping插件创建的。在服务器端,我有3个viewmodel,它们是: EmployeeModel(包含ServiceEmployeeModel的列表) ServiceModel(包含

在我的模式中,两个表Service和Employee之间存在多对多关系(一个服务可以由多个员工执行,一个员工可以执行多个服务) . 我使用ServiceEmployee连接表来创建此关系

我在客户端使用knockout。knockout viewmodels是通过服务器端viewmodel中的knockout.mapping插件创建的。在服务器端,我有3个viewmodel,它们是:

  • EmployeeModel(包含ServiceEmployeeModel的列表)

  • ServiceModel(包含ServiceEmployeeModel的列表)

  • ServiceEmployeeModel(包含ServiceId、EmployeeId)[不能包括员工和 服务对象,以避免客户端的自引用循环]

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

    员工模块

    服务模块

    ServiceEmployee模块

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


    计算可观测可能是解决方案,但我不知道如何解决。有人能帮我解决这个问题吗?

    解决方案A:

    您可能希望尝试breeze:它们不直接支持多对多关系,但如果您像这样公开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
    
    如果您想使用breeze,您必须阅读其他breeze功能,例如加载和保存数据等

    解决方案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;
    }
    
    如果我正确地编写了映射部分(不确定是否正确,请查看此处了解更多详细信息),那么当您取消映射员工模型时,映射插件应该忽略您的ServiceObjects

    您还可以添加一个写入函数,通过从服务阵列中添加和删除对象来响应ServiceObjects阵列中的更改,从而添加到阵列中

    解决方案C:


    看看另一个解决方案:

    当您谈到自引用循环时,您是指运行toJSON时吗?
    Service.Employees // Array of ServiceEmployee
    ServiceEmployee.Employee // Employee
    ServiceEmployee.Service // Service
    Employee.Services // Array of ServiceEmplyee
    
    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
    
    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;
    }