jQuery-file-upload: 调试间歇性 "not initialized" 添加回调错误

jQuery-file-upload: debugging intermittent "not initialized" error in add callback

我正在使用 jQuery 文件上传和 KnockoutJS 构建资产管理器。麻烦的是,当我上传一组几个文件时,在看似随机的时间我收到异常

Uncaught Error: cannot call methods on fileupload prior to initialization; attempted to call method 'process'

在集合中的一个文件的 add 回调中间。

每次将文件添加到上传队列时,我都会先执行 AJAX 请求,以便 'pre-register' 服务器上的新资产。之后,我调用 jquery.fileupload-process 插件以执行 client-side 文件验证。简体:

function add(ev, data) {
  // perform an AJAX request through the Knockout view model
  viewModel.addAsset().done(function(asset) {
    data.asset = asset;

  }).done(function() {

    data.process(function () {
      return $element.fileupload('process', data); // EXCEPTION OCCURS HERE

    }).done(function() {
      data.submit();
    });

  });
};

这个问题似乎与时间有关,而不是其他任何问题。同一组 20 个文件正在上传,有时会在第五个、第七个、第十五个文件上出现错误 - 或者根本不会出现错误。

这里是绑定的完整代码:

ko.bindingHandlers.uploader = {
  init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var $element          = $(element),
        options           = ko.unwrap(valueAccessor()),
        fileUploadConfig,
        fileUpload,
        doneHandler;

    fileUploadConfig = {
      dataType: 'json',
      type: 'PUT',
      url: '/assets', // will be overriden individually after processing
      autoUpload: true,
      sequentialUploads: true,
      dropZone: options.dropzone,
      acceptFileTypes: /(\.|\/)(jpe?g|png|mp3|aac|mp4)$/i,
      maxFileSize: 250000000
    };

    fileUploadConfig.add = function add(ev, data) {
        if (DEBUG) { console.assert(data.files.length === 1, "expected the add handler to be called with a single file, got " + data.files.length); }

        var kind      = data.files[0].type.split('/')[0],
            file_name = data.files[0].name;

        console.log("adding %s", file_name);

        viewModel.addAsset(kind).done(function(asset) {
          console.log("AJAX call complete, Knockout data model created for file %s", file_name);

          data.asset = asset;

          data.asset.upload_file_name(file_name);
          data.asset.upload_status('waiting');

          data.url = asset.resource_path;

        }).done(function() {

          data.process(function () {
            console.log("calling processing plugin for file %s", file_name);

            // EXCEPTION OCCURS HERE              
            return $element.fileupload('process', data);

          }).done(function() {
            console.log('processing done, submitting %s', file_name);
            data.submit();
          });

        });

    };

    fileUploadConfig.done = function done(e, data) {
      app.services.Asset.refresh(data.asset)
        .done(function(asset) {
          asset.upload_status('done');
        });
    };

    fileUploadConfig.send = function send(e, data) {
      console.log("sending file %s", data.files[0].name);
      data.asset.upload_progress(0);
      data.asset.upload_status('uploading');
    };

    fileUploadConfig.progress = function progress(e, data) {
      if (data.asset.upload_status() !== 'uploading') {
        return;
      }

      var percentage = parseInt(data.loaded / data.total * 100, 10);

      if (percentage >= 100) {
        data.asset.upload_status('processing');
        data.asset.upload_progress(null);
      } else {
        data.asset.upload_progress(percentage);
      }
    };

    fileUploadConfig.fail = function fail(e, data) {
      console.log("failure file %s", data.files[0].name);
      data.asset.upload_status('failed');

      app.services.Base._defaultFailureHandler(data.jqXHR);
      app.services.Base.failure422Handler(data.jqXHR);
    };

    console.log("initializing jQ fileUpload");

    fileUpload = $element.fileupload(fileUploadConfig);
  }
};

控制台调试语句的示例输出如下所示:

在我已经成功处理文件后,jQuery 文件上传突然没有初始化对我来说完全没有意义。这是异常发生时我的调用堆栈:

如果我因异常暂停,转到我在 return $element.fileupload('process', data); 的框架并在控制台中检查 $element.data(),我收到

Object {bind: "uploader: {dropzone: $('.upload-manager-overlay')}"}

— jQuery 文件上传当然还在。

很抱歉没有提供工作 fiddle,但我无法提供此工作所需的上传服务器端点。

如果有任何提示或进一步的调试建议,我将不胜感激。

原来我做了一些愚蠢的事情:<input type=file> jQuery 文件上传附加到是 Knockout 渲染信息面板的一部分。第一个文件成功传输后,此信息面板已被删除。

jQuery 文件上传不能很好地绑定到已从 DOM.

分离的 DOM 元素。