我有一个 loopback-js API。
其中我有一个产品模型,它相当复杂,有许多相关模型。 (元数据、技术要求、标签、域、目标受众……)
我正在编写 CMS,我希望用户能够轻松复制产品,然后只需更改一些小东西,因为所有这些产品的许多数据都是相同的。
在 Loopback JS 中是否有一种简单的方法可以做到这一点?例如 product.saveAs();
我看到的唯一方法是从产品中获取数据,然后删除 id 并将数据作为新产品插入数据库中,然后对所有相关模型执行相同操作...
最佳答案
因为我在网上找不到简单的答案,所以我想出了一个可以用模型实现的混合。 mixin 定义了一个 duplicate 方法,它通过检查模型定义来复制模型,因此它遍历关系树,以复制或链接相关项:
common/mixins/duplicate.js 中的 mixin 文件
var async = require('async');
function Duplicate(Model){
Model.duplicate = function (id, cb) {
var self = this;
var models = Model.app.models;
var includeRelations = Object.keys(self.definition.settings.relations);
self.findById(id, {include: includeRelations}, function(err, fromInstance){
if(err){
return cb(err);
}
var fromData = JSON.parse(JSON.stringify(fromInstance));
delete fromData.id;
self.create(fromData, function(err, newInstance){
if(err){
return cb(err);
}
var relations = self.definition.settings.relations;
var operations = [];
for(var relationName in relations){
var relation = relations[relationName];
switch(relation.type){
case "hasAndBelongsToMany": //add extra links to relation
if(relation.foreignKey == "") relation.foreignKey = "id";
for(var i = 0; i < fromData[relationName].length; i++){
var relatedItem = fromData[relationName][i];
operations.push(async.apply(newInstance[relationName].add, relatedItem[relation.foreignKey]));
}
break;
case "hasMany": //create extra items
if(relation.through){
//don copy many through relations, add an extra has many on the intermediate
} else {
// copy ze shit, and recursively check if child relations have to be duplicated
for(var i = 0; i < fromData[relationName].length; i++) {
var relatedItem = fromData[relationName][i];
operations.push(async.apply(
function(relation, relatedItem, newInstance, cb2){
try {
models[relation.model].duplicate(relatedItem.id, function(err, duplicatedInstance){
if(err){
cb2(err);
}
var fk = relation.foreignKey || self.definition.name.substr(0, 1).toLowerCase() + self.definition.name.substr(1) + "Id";
duplicatedInstance.updateAttribute(fk, newInstance.id , cb2);
});
} catch(err){
cb2(err);
}
},
relation, relatedItem, newInstance));
}
}
break;
default: //do nothing
}
}
if(operations.length > 0){
async.parallel(operations, function (err, results) {
if (err) cb(err);
cb(null, newInstance);
});
} else {
cb(null, newInstance);
}
});
})
}
}
module.exports = Duplicate;
更新您的模型配置:
{
"_meta": {
"sources": [
"loopback/common/models",
"loopback/server/models",
"../common/models",
"./models"
],
"mixins": [
"loopback/common/mixins",
"../common/mixins"
]
},
在需要的地方定义模型,你想使用mixin:
...
"acls": [
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "DENY"
}
],
"methods": [],
"mixins": {
"Duplicate": true
}
使用风险自负
它远非完美,但就目前而言,它足以满足我的需要。也许其他人也可以使用它。
目前它复制模型数据本身(包括 belongsTo 关系的外键和嵌入式模型)、hasMany(递归)和 hasToAndBelongsToMany(非递归)。如果您想要 hasManyThrough 功能,最好向“through-table”添加一个额外的 hasmany-relation,它将被复制。
我以后可能会添加的内容:
- 检查是否在有效的环回模型上调用了 mixins
- 添加选项以指定应包括哪些关系
- 添加 has-many-through 功能
关于javascript - 如何在 Loopback JS 中轻松复制模型和相关模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30799706/