无法在回调函数中调用任何fineUploader方法

5
我将autoUpload设置为false,因为我想自己将图片上传到后端。但是,要做到这一点,我首先需要文件对象。在回调的onSubmitted事件中,我试图将图片ID传递给getFile方法,以返回该对象。然而,当我尝试这样做时,我会收到下面的错误信息:

在onSubmitted中:id=0 | name=28603454_15219061700_r.jpg index.js:2178

[Fine Uploader 5.16.2] Caught exception in 'onSubmitted' callback - Cannot read property 'uploader' of null

我猜测这是因为我同时声明了一个const对象并引用了它,这是不允许的...
那么,你有什么办法可以在callbacks函数内调用方法吗?还是有其他方法?
const uploader = new FineUploaderTraditional({
  options: {
    maxConnections: 1,
    autoUpload: false,
    deleteFile: { enabled: true, endpoint: "/uploads" },
    request: { endpoint: "/uploads" },
    retry: { enableAuto: true },
    callbacks: {
      onSubmitted: function(id, name) {
        console.log("in onSubmitted: id=" + id + " | name=" + name);
        // getFile(id) returns a `File` or `Blob` object.
        console.log(this.uploader.getFile(id));
      }
    }
  }
});

更新 我把我的fine-uploader代码全部提取出来,创建了一个新的组件。但我仍然遇到了同样的问题。下面是该组件的代码:

FineUploader.jsx

import React, { Component } from "react";
import FineUploaderTraditional from "fine-uploader-wrappers";
import Gallery from "react-fine-uploader";
import Filename from "react-fine-uploader/filename";
import "react-fine-uploader/gallery/gallery.css";

const util = require("util");

const uploader = new FineUploaderTraditional({
  options: {
    // debug: true,
    maxConnections: 1,
    autoUpload: false,
    deleteFile: { enabled: true, endpoint: "/uploads" },
    request: { endpoint: "/uploads" },
    retry: { enableAuto: true },
    validation: {
      acceptFiles: ".jpg,.png,.gif,.jpeg",
      allowedExtensions: ["jpg", "png", "gif", "jpeg"],
      itemLimit: 5,
      sizeLimit: 5000000
    },
    callbacks: {
      onCancel: function() {
        console.log("in onCancel: ");
      },
      onComplete: function(id, name, responseJSON, xhr) {
        console.log("in onComplete: " + id + " | " + name + " | " + responseJSON + " | " + xhr);
      },
      onAllComplete: function(succeeded, failed) {
        console.log("in onAllComplete: " + succeeded + " | " + failed);
      },
      onProgress: function(id, name, uploadedBytes, totalBytes) {
        console.log("in onProgress: " + id + " | " + name + " | " + uploadedBytes + " | " + totalBytes);
      },
      onError: function(id, name, errorReason, xhr) {
        console.log("in onError: " + id + " | " + name + " | " + errorReason + " | " + xhr);
      },
      onDelete: function(id) {
        console.log("in onDelete: " + id);
      },
      onDeleteComplete: function(id, xhr, isError) {
        console.log("in onDeleteComplete: " + id + " | " + xhr + " | " + isError);
      },
      onPasteReceived: function(blob) {
        console.log("in onPasteReceived: " + blob);
      },
      onResume: function(id, name, chunkData, customResumeData) {
        console.log("in onResume: " + id + " | " + name + " | " + chunkData + " | " + customResumeData);
      },
      onStatusChange: function(id, oldStatus, newStatus) {
        console.log("in onStatusChange: " + id + " | " + oldStatus + " | " + newStatus);
      },
      onSubmit: function(id, name) {
        console.log("in onSubmit: " + id + " | " + name);
      },
      onSubmitted: function(id, name) {
        console.log("in onSubmitted: id=" + id + " | name=" + name);
        // getFile(id) returns a `File` or `Blob` object.
        // console.log(this.uploader.getFile(id));
        // console.log(uploader.getFile(id));
        // nothing here is working.... :(
      },
      onUpload: function(id, name) {
        console.log("in onUpload: " + id + " | " + name);
      },
      onValidate: function(data, buttonContainer) {
        console.log(
          "in onValidate: " + util.inspect(data, { showHidden: true, depth: null }) + " | " + buttonContainer
        );
      },
      onSessionRequestComplete: function(response, success, xhrOrXdr) {
        console.log("in onSessionRequestComplete: " + response + " | " + success + " | " + xhrOrXdr);
      }
    }
  }
});

const fileInputChildren = <span>Click to Add Photos</span>;
const statusTextOverride = {
  upload_successful: "Success!"
};

class FineUploader extends Component {
  constructor() {
    super();

    this.state = {
      submittedFiles: []
    };
  }

  componentDidMount() {
    uploader.on("submitted", id => {
      const submittedFiles = this.state.submittedFiles;
      console.log("submittedFiles: " + submittedFiles);

      submittedFiles.push(id);
      this.setState({ submittedFiles });
    });
  }

  render() {
    return (
      <div>
        {this.state.submittedFiles.map(id => (
          <Filename id={id} uploader={uploader} />
        ))}
        <Gallery
          fileInput-children={fileInputChildren}
          status-text={{ text: statusTextOverride }}
          uploader={uploader}
        />
      </div>
    );
  }
}

export default FineUploader;

而 -- 现在在主页上,我正在导入FineUploader.jsx,并使用该组件。

import FineUploader from "../../components/FineUploader";

在我的渲染方法中,我有以下内容:
<FineUploader />

抱歉打错字了:赏金应该是“我已经将...外部化” - ElasticThoughts
你的意思是在 onSubmit 中,即使是这一行代码 console.log("in onSubmitted: id=" + id + " | name=" + name); 也没有被执行吗? - MT-FreeHK
console.log 正常工作。 - ElasticThoughts
你尝试过将 this 绑定到 onSubmit 中吗?例如 onSubmitted: (id, name) =>{...this.uploader...} - MT-FreeHK
我以前做过类似的事情,比如在构造函数中。但是不确定如何在这里,在回调事件中实现...你能提供一个可行的例子吗? - ElasticThoughts
就像我在上一条评论中写的那样...使用箭头函数。 - MT-FreeHK
2个回答

4
在JavaScript中,this是一个棘手的问题。在常规函数(例如function f(){...})中,this依赖于函数被调用的位置而不是定义的位置。当通过第三方API使用回调函数时,您不能真正控制它被调用的位置,因此可能会出现上面所述的错误。
幸运的是,您可以使用箭头函数(例如const f = () => {...};)来基于函数定义的位置绑定this
有关更多信息,请参见MDN文档或参考这个很好的SO答案
然而,对于您特定的代码,我不确定这两种方法是否都适用,因为您在定义onSubmitted时的this只是全局/窗口对象。
为了使其工作,您需要在顶层创建一个闭包(就在您实际创建上传器之前):
function onSubmitted(id, name) {
    console.log("in onSubmitted: id=" + id + " | name=" + name);
    // getFile(id) returns a `File` or `Blob` object.
    console.log(uploader.getFile(id));
}

const uploader = new FineUploaderTraditional({..., callbacks: {onSubmitted, ...}});

这将允许您在实例化上传程序之前定义与其交互的逻辑(这似乎正是您想要的)。请注意,由于我们只是利用js闭包规则,因此缺少this

0

不要使用console.log(this.uploader.getFile(id));,尝试使用:

console.log(uploader.methods.getFile(id));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接