我有一个文件上传组件,我试图将数据和图像一起传递给控制器,这样我就可以创建照片对象。 一些数据是诸如磁盘之类的东西,例如“S3”,因此控制器将知道将图像存储在何处。 但是,FilePond 似乎不允许将任何变量、道具或 vuex 状态传递到 FilePond 实例中。无论我如何尝试,它总是说它总是未定义的。 在 FilePond 中,它说您可以使用 formData.append('Hello', 'World')
FilePond.setOptions({
server: {
url: 'http://192.168.0.100',
timeout: 7000,
process: {
url: './process',
method: 'POST',
headers: {
'x-customheader': 'Hello World',
},
withCredentials: false,
onload: (response) => response.key,
onerror: (response) => response.data,
ondata: (formData) => {
formData.append('Hello', 'World');
return formData;
},
},
revert: './revert',
restore: './restore/',
load: './load/',
fetch: './fetch/',
},
});
但是如果你为
子'世界'
this.photo.disk,或
state.photoUploader.photo.disk 或
this.$store.state.photoUploader.photo.disk 或 mapState 并使用
照片
或任何它总是未定义的。它不知道这个 filepond 实例之外是什么。
还有你可以传递的文件元数据对象。这也有同样的问题。我可以整天传递字符串并且它有效,但是一旦您尝试传递任何类型的变量,它就不知道它是什么。 https://pqina.nl/filepond/docs/api/plugins/file-metadata/
FilePond.setOptions({
fileMetadataObject: {
hello: 'world',
},
});
我只尝试了原始元数据选项
metadata: {
date: '2018-10-5T12:00',
},
我提到的所有变量都在 console.log 中显示它们的值,并在组件中显示它们时,但在 filepond 实例中不起作用。我需要能够将带有照片的数据发送到控制器以创建照片对象。
这是我的组件的示例(仅供参考,我将所有不同类型的变量作为我尝试过的示例):
<template>
<div>
<Head title="Photo Uploader" />
<Card
class="flex flex-col items-center justify-center h-full"
>
<!-- Photo Fields -->
<div class="flex flex-col w-full pb-1 pt-8">
<div class="flex flex-row w-full">
<div class="pr-4">
<validation-check :validated="photoFieldsExists"></validation-check>
</div>
<div class="flex flex-col">
<heading class="pb-2">Step 5: Upload Images: </heading>
<h1>Click to choose images, or drag and drop into box.</h1>
<h1 class="mb-6">{{ photo }}</h1>
</div>
</div>
<div class="w-full h-full">
<file-pond
name="image"
ref="pond"
label-idle="Click to choose images, or drag here..."
@init="handleFilePondInit"
accepted-file-types="image/*"
/>
</div>
</div>
</Card>
</div>
</template>
<script>
import ApiUrls from "../../components/mixins/ApiUrls";
import ValidationCheck from './ValidationCheck';
import {mapState} from 'vuex';
// Import FilePond
import vueFilePond, { setOptions } from 'vue-filepond';
// Import plugins
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.esm.js';
import FilePondPluginFileMetadata from 'filepond-plugin-file-metadata';
// import FilePondPluginImagePreview from 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.esm.js';
// Import styles
import 'filepond/dist/filepond.min.css';
// import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
setOptions({
server: {
process: {
url: Nova.config('apiUrl') + '/photos',
headers: {
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
},
ondata: (formData) => {
formData.append('photo_group_id', this.photoGroupId);
formData.append('photo_type_id', this.photoTypeId);
formData.append('disk', this.photo.disk);
formData.append('title', this.photo.title);
formData.append('alt', this.photo.alt);
formData.append('description', this.photo.description);
formData.append('src', this.photo.src);
formData.append('sub_folder', this.photo.subFolder);
return formData;
},
}
},
fileMetadataObject: {
photo_group_id: "photo.photo_group_id",
photo_type_id: "this.$store.state.photoUploader.photoTypeId",
disk: "photo.disk",
title: "this.photo.title",
alt: "state.photoUploader.photo.alt",
description: "",
src: "",
sub_folder: "",
},
});
const FilePond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginFileMetadata
);
export default {
components: {
ValidationCheck,
FilePond
},
mixins: [ApiUrls],
props: ["photo"],
computed: {
// TODO: Change setOptions to pull from computed properties
...mapState({
photo: state => state.photoUploader.photo,
photoTypeId: state => state.photoUploader.photoTypeId,
photoGroupId: state => state.photoUploader.photoGroupId
})
},
data() {
return {
includesPhotos: '?include=photos',
metaData: {
photo_group_id: this.$store.state.photoUploader.photoGroupId,
photo_type_id: this.$store.state.photoUploader.photoTypeId,
disk: this.$store.state.photoUploader.photo.disk,
title: this.$store.state.photoUploader.photo.title,
alt: this.$store.state.photoUploader.photo.alt,
description: this.$store.state.photoUploader.photo.description,
src: this.$store.state.photoUploader.photo.src,
sub_folder: this.$store.state.photoUploader.photo.subFolder
},
// photo: this.photo,
// photoGroupId: this.photoGroupId,
// photoTypeId: this.photoTypeId,
}
},
mounted() {
this.fetchData();
},
methods: {
fetchData() {
console.log('fetch data in upload handler');
console.log('Photo: ');
console.log(this.$store.state.photoUploader.photo);
console.log('PhotoTypeId: ');
console.log(this.$store.state.photoUploader.photoTypeId);
},
handleFilePondInit: function () {
console.log('FilePond has initialized');
console.log('FilePond Object: ', this.$refs.pond)
// example of instance method call on pond reference
this.$refs.pond.getFiles();
console.log('handle file pond 1:')
console.log(this.$refs.pond.getFiles());
// console.log('this.state.files: ');
// console.log(this.state.files);
},
}
}
</script>
<style>
/* Scoped Styles */
</style>
我也试过将它传递给 fileponds 自定义服务器选项,但没有成功。这是他们的例子:
FilePond.setOptions({
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
// fieldName is the name of the input field
// file is the actual file object to send
const formData = new FormData();
formData.append(fieldName, file, file.name);
const request = new XMLHttpRequest();
request.open('POST', 'url-to-api');
// Should call the progress method to update the progress to 100% before calling load
// Setting computable to false switches the loading indicator to infinite mode
request.upload.onprogress = (e) => {
progress(e.lengthComputable, e.loaded, e.total);
};
// Should call the load method when done and pass the returned server file id
// this server file id is then used later on when reverting or restoring a file
// so your server knows which file to return without exposing that info to the client
request.onload = function () {
if (request.status >= 200 && request.status < 300) {
// the load method accepts either a string (id) or an object
load(request.responseText);
} else {
// Can call the error method if something is wrong, should exit after
error('oh no');
}
};
request.send(formData);
// Should expose an abort method so the request can be cancelled
return {
abort: () => {
// This function is entered if the user has tapped the cancel button
request.abort();
// Let FilePond know the request has been cancelled
abort();
},
};
},
},
});
我正面临这个问题,您需要使用此线程中包含的建议。
https://github.com/pqina/vue-filepond/issues/99
FilePond 有很多方法和事件,为什么要尝试直接在服务器设置选项中添加一些东西?你不必要地复杂化了你的逻辑。