我想做的事: 有一个 html 表单,里面有一个文件输入。选择文件后,文件输入应上传文件,并获取文件 ID,因此提交表单时,文件 ID 会随表单一起发布并写入数据库。
简短版本:我想将元数据(例如 ID)与我的文件一起存储。
听起来很简单,但我很难在 LoopBack 中做到这一点。
关于这个主题已经有过几次对话( 1 , 2 ),但似乎都没有找到解决方案,所以我认为这可能是一个一劳永逸地找到解决方案的好地方。
最简单的解决方案是使用模型关系,但LoopBack不支持与文件存储服务的关系。撞。因此,我们必须使用名为 File
的持久模型,并覆盖默认的创建、删除,以便它从我名为 Storage
的文件存储模型中保存和删除。
到目前为止我的设置:
- 我有一个模型/api/Storage,它连接到 loopback storage service并成功将文件保存到本地文件系统。
- 我有一个连接到 Mongo 的 PersistedModel,其中包含文件元数据:
name
、size
、url
和objectId
- 我在
create
之前设置了一个远程 Hook ,因此可以先保存文件,然后将其url
注入(inject)File.create()
我在那里,根据this LoopBack page ,我有 ctx,里面应该有文件:
File.beforeRemote('create', function(ctx, affectedModelInstance, next) {})`
什么是ctx
?
ctx.req
: Express Request object.
ctx.result
: Express Response object.
好吧,现在我在 Express 页面上,非常迷失,它提到了一些关于“正文解析中间件”的内容,但我不知道它可能是什么。
我觉得我已经接近解决方案了,任何帮助将不胜感激。这种做法对吗?
最佳答案
这是在环回中使用文件存储元数据的完整解决方案。
您需要一个容器模型
common/models/container.json
{
"name": "container",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
在 server/datasources.json
中为容器创建数据源。例如:
...
"storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "/var/www/storage",
"maxFileSize": "52428800"
}
...
您需要将 server/model-config.json
中此模型的数据源设置为您拥有的 loopback-component-storage
:
...
"container": {
"dataSource": "storage",
"public": true
}
...
您还需要一个文件模型来存储元数据并处理容器调用:
common/models/files.json
{
"name": "files",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string"
},
"url": {
"type": "string",
"required": true
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
现在将文件
与容器
连接:
common/models/files.js
var CONTAINERS_URL = '/api/containers/';
module.exports = function(Files) {
Files.upload = function (ctx,options,cb) {
if(!options) options = {};
ctx.req.params.container = 'common';
Files.app.models.container.upload(ctx.req,ctx.result,options,function (err,fileObj) {
if(err) {
cb(err);
} else {
var fileInfo = fileObj.files.file[0];
Files.create({
name: fileInfo.name,
type: fileInfo.type,
container: fileInfo.container,
url: CONTAINERS_URL+fileInfo.container+'/download/'+fileInfo.name
},function (err,obj) {
if (err !== null) {
cb(err);
} else {
cb(null, obj);
}
});
}
});
};
Files.remoteMethod(
'upload',
{
description: 'Uploads a file',
accepts: [
{ arg: 'ctx', type: 'object', http: { source:'context' } },
{ arg: 'options', type: 'object', http:{ source: 'query'} }
],
returns: {
arg: 'fileObject', type: 'object', root: true
},
http: {verb: 'post'}
}
);
};
要公开文件 api,请添加到 files
模型的 model-config.json
文件中,请记住选择正确的数据源:
...
"files": {
"dataSource": "db",
"public": true
}
...
完成! 现在,您可以使用 file
表单字段中的文件二进制数据调用 POST /api/files/upload
。您将得到 id、名称、类型和 url 作为返回。
关于loopbackjs - 如何在LoopBack中存储带有元数据的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28885282/