如何从 Fine-Uploader 回调中引用外部 JavaScript 函数?

How can I reference external JavaScript functions from Fine-Uploader callback?

我的 user-profile.html 中有以下代码:

<template>
    <!--Fine-Uploader HTML is here
    ...-->
    <script>
        var uploader = new qq.FineUploader({
            element: document.getElementById("uploader"),
            debug: true,
            cors: {
                expected: true
            },
            request: {
                endpoint: configOptions.baseUrl + '/api/assets',
                customHeaders: {
                    Authorization: "Bearer " + localStorage.getItem("aurelia_id_token")
                }
            },
            multiple: false,
            callbacks: {
                onComplete: function (id, fileName, responseJSON){
                    updateProfile(responseJSON.displayUrl);
                }
            } 
        });  
    </script>
</template>

如您所见,我想在成功完成上传后调用 updateProfile。我得到了 onComplete 回调,并且正确地解析了 JSON 响应对象。问题是 updateProfile 函数在一个单独的 .js 文件中,名为 user-profile.js

我在 Aurelia 工作,这是创建 MVVM 模块的标准约定,即使用 .html.js 扩展名命名文件。我不确定为什么他们在这种情况下不共享范围,但我收到错误消息:

Caught exception in 'onComplete' callback - updateProfile is not defined

我也试过在索引文件中简单地添加一个标准的脚本标签,直接引用 .js 文件,但它也不起作用,而且看起来是个坏主意。

如能提供任何相关指导,我们将不胜感激。

您不能在 Aurelia 模板中放置 script 个元素。您需要将代码移动到您的 Aurelia VM 中,或者移动到您导入到 VM 中的单独模块中。

对于第三方库,jQuery 插件等,最好将其封装在自定义属性或自定义元素中。另外,正如 Ashley 所说,模板中不能有 script 元素。

fine-uploader 是自定义元素的一个很好的候选者。这是我在我的一个项目中使用的简化版本:

<!-- fine-uploader.html -->
<template>
  <a href="#" class="btn btn-default" role="button">Upload image</a>
</template>
// fine-uploader.js
import fine from 'fine-uploader';
import {bindable, inject} from 'aurelia-framework';

@inject(Element)
export class FineUploader {

  @bindable endpoint;            // URL to upload to
  @bindable params = {};         // Any additional upload params
  @bindable uploaded = () => {}; // Uploaded callback for consumers

  constructor(element) {
    this.element = element;
  }

  attached() {
    this.uploader = new fine.FineUploaderBasic({
      debug: true,
      button: this.element.children[0],
      callbacks: {
        onComplete: (id, name, response) => {
          if (this.uploaded) {
            this.uploaded(response);
          }
        }
      },
      request: {
        endpoint: this.endpoint,
        customHeaders: {
          'authorization': `Bearer ${localStorage.getItem("aurelia_id_token")}`
        },
        method: 'PUT',
        params: this.params
      },
      scaling: {
        sendOriginal: false,
        sizes: [{ maxSize: 500 }]
      },
      validation: {
        acceptFiles: '.jpg,.png'
      }
    });
  }

  detached() {
    // Apparently, no destroy() method
    // https://github.com/FineUploader/fine-uploader/issues/1038
    //this.uploader.reset();
  }
}

这样,您就可以从多个地方使用同一个组件。以下是您案例的示例用法:

<!-- user-profile.html -->
<template>
  <require from="../resources/elements/fine-uploader"></require>

  <!-- ... -->
  <fine-uploader endpoint="/api/assets" params.bind="uploadParams" 
                 uploaded.call="imageUploaded($event)"></fine-uploader>
</template>
// user-profile.js
export class UserProfile {

  activate(id) {
    this.uploadParams = {
      userId: id // And/or any other data you need to send with the image upload
    }
  }

  imageUploaded(response) {
    this.updateProfile(response.displayUrl);
  }

  updateProfile(url) {
    // ...
  }
}