Laravel Nova Vue 将额外数据传递给 FilePond 上传

问题描述 投票:0回答:1

我有一个文件上传组件,我试图将数据和图像一起传递给控制器,这样我就可以创建照片对象。 一些数据是诸如磁盘之类的东西,例如“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();
                },
            };
        },
    },
});
laravel vue.js file-upload laravel-nova filepond
1个回答
0
投票

我正面临这个问题,您需要使用此线程中包含的建议。

https://github.com/pqina/vue-filepond/issues/99

FilePond 有很多方法和事件,为什么要尝试直接在服务器设置选项中添加一些东西?你不必要地复杂化了你的逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.