我有一个loopback-js API。
在其中我有一个相当复杂的产品模型,有许多相关模型。 (元数据,技术要求,标签,域名,targetAudience,...)
我正在编写CMS,我希望用户能够轻松地复制产品,然后只需更改一些小东西,因为所有这些产品的许多数据都是相同的。
在Loopback JS中有一种简单的方法吗? E.g product.saveAs();
我看到的唯一方法是从产品中获取数据,然后删除id并将数据作为新产品插入数据库中,然后对所有相关模型执行相同操作...
答案 0 :(得分:4)
由于我在网上找不到简单的答案,我想出了一个可以用模型实现的mixin。 mixin定义了一个重复的方法,它通过检查模型定义来复制模型,因此它遍历关系树,复制或链接相关项:
共同的mixin文件/ mixins / duplicate.js
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;
更新您的model-config:
{
"_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,它将被复制。
我将来可能添加的内容: