我在两个表Service和Employee之间的模式中有多对多的关系(一个服务可以由多个员工执行,一个Employee可以执行多个服务).我使用ServiceEmployee联结表来创建此关系.
我在客户端使用淘汰赛.淘汰视图模型是通过服务器端viewmodel的knockout.mapping插件创建的.在服务器端,我有3个viewmodel,它们是:
EmployeeModel(包含ServiceEmployeeModel列表)
ServiceModel(包含ServiceEmployeeModel列表)
ServiceEmployeeModel(包含ServiceId,EmployeeId)[不能包含Employee和Service对象以避免客户端的自引用循环]
现在在客户端我有3个模块:
员工模块
function Employee(data)
{
var self = this;
ko.mapping.fromJS(data, {
"Services": {
create: function (options) {
return new serviceEmployee(options.data, options.parent);
}
}
}, self);
....
}
Run Code Online (Sandbox Code Playgroud)
服务模块
function Service(data)
{
var self = this;
ko.mapping.fromJS(data, {
"Employees": {
create: function (options) {
return new serviceEmployee(options.data, options.parent);
}
}
}, self);
....
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用的方法是工作,但我觉得应该有一些其他更好的方法来处理这种情况.因为在这种方法中,如果我们将服务分配给Employee OR Employees to Service,那么我们必须手动更新Employees和Services数组,我觉得应该有更好的方法,以便knockout将为我更新这些数组.
计算的可观察量可能是解决方案,但我无法得到它.有谁可以帮我解决这个问题?
方案一:
您可能想尝试微风:http://www.breezejs.com/他们不直接支持多对多关系,但如果您像这样公开 navigaiton 对象:
Service.Employees // Array of ServiceEmployee
ServiceEmployee.Employee // Employee
ServiceEmployee.Service // Service
Employee.Services // Array of ServiceEmplyee
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
如果您想使用微风,您必须阅读其他微风功能,例如加载和保存数据等。
方案B:
您可能想查看 ko.mapping 插件的忽略属性,例如尝试以下操作:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果我正确地编写了映射部分(不确定我是否正确,请在此处查看更多详细信息http://knockoutjs.com/documentation/plugins-mapping.html),那么当您取消映射员工模型时,映射插件应该忽略您计算的 ServiceObjects
您还可以添加一个写入函数,通过在 Services 数组中添加和删除对象来添加到数组中,以响应 ServiceObjects 数组中的更改。
方案C:
看看另一个解决方案:Knockout JS ObservableArray with multiple-to-many transactions