简体   繁体   English

文件上传完成后如何调用JS回调?

[英]How do I call a JS callback when a file upload completes?

I'm creating frontend upload for an app with appengine backend. 我正在为带有appengine后端的应用创建前端上传。

What I want to make is a file upload solution, and I dont want to be using plupload or those kinds of ready-made solutions. 我想要的是一个文件上传解决方案,我不想使用plupload或那些现成的解决方案。

I basically submitted the images to an iframe and then put a cover while it is uploading. 我基本上将图像提交给iframe,然后在上传时盖上封面。 Then after it finishes I performed an ajax call to get the image ids for the next view to be rendered. 然后,在完成后,我执行了一个ajax调用,以获取要渲染的下一个视图的图像ID。 However, the render is always called before the upload is completed, thus I'm not getting any image ids from the backend. 但是,在上传完成之前总是调用渲染,因此我没有从后端获取任何图像ID。 can anyonehelp? 谁能帮忙?

here's my code for the upload 这是我上传的代码

perform_input3:(event)=>
    event.preventDefault()
    $('#product-input-3').hide()
    $('#product-input-3').submit()
    $('#upload-cover').show()
    item_id = $('#item3_id').val()
    app.views.imageselect.render(item_id)

the app.views.imageselect.render(item_id) is below: app.views.imageselect.render(item_id)如下:

render:(data)=>
    @item_id = data
    item_id = @item_id
    $.ajax(
        url: '/get_image_list/'
        type: 'GET'
        dataType: 'json'
        data: {item_id: item_id}
        success:(data) =>
          @payload = data
          $(@el).append imageSelectTemplate(@payload)
          return @
    )

I dont want to be using setTimeout function since it will not be flexible depending on the connection speed. 我不想使用setTimeout函数,因为它不会灵活,具体取决于连接速度。 Any help will be appreciated :) 任何帮助将不胜感激 :)

Essentially, your question boils down to this: You want to wait to make your Ajax call to the server until the data you're requesting is available. 从本质上讲,您的问题归结为:您希望等待对您的Ajax调用服务器,直到您请求的数据可用。 Getting notifications from the server is tricky (depending on how your backend is implemented), so the best solution to your problem is probably to just make the Ajax call periodically (say, once per second) until you get a successful response from the server. 从服务器获取通知很棘手(取决于后端的实现方式),因此解决问题的最佳方法可能是定期(例如,每秒一次)进行Ajax调用,直到从服务器获得成功响应。

Here's some code that should do that: 这里有一些应该这样做的代码:

do ajaxCall = =>
  $.ajax
    url: '/get_image_list/'
    type: 'GET'
    dataType: 'json'
    data: {item_id: item_id}
    success: (data) =>
      @payload = data
      $(@el).append imageSelectTemplate(@payload)
    error: ->
      setTimeout ajaxCall, 1000

If you are only targeting modern browsers, then XHR2's FormData can enable a very simple and elegant approach. 如果您只针对现代浏览器,那么XHR2的FormData可以实现非常简单和优雅的方法。

The concept is: 这个概念是:

  • add file(s) binary data to a FormData object 将文件二进制数据添加到FormData对象
  • make a $.ajax() call with the FormData object as the AJAX call's "data" parameter 使用FormData对象作为AJAX调用的“data”参数进行$ .ajax()调用
  • when upload is done, the $.ajax()'s success() or complete() callbacks will be triggered 上传完成后,将触发$ .ajax()的success()或complete()回调

This approach works with the latest Firefox, Chrome, Safari - http://caniuse.com/xhr2 . 这种方法适用于最新的Firefox,Chrome,Safari - http://caniuse.com/xhr2

See this post for details: Sending multipart/formdata with jQuery.ajax 有关详细信息,请参阅此文章: 使用jQuery.ajax发送multipart / formdata

What you're missing is some sort of callback from the $('#product-input-3').submit() call. 你缺少的是来自$('#product-input-3').submit()调用的某种回调。 I think the following would work (pardon my bad CoffeeScript): 认为以下内容可行(请原谅我糟糕的CoffeeScript):

perform_input3:(event)=>
    event.preventDefault()
    item_id = $('#item3_id').val()
    $('#product-input-3').hide()
    $('#upload-cover').show()
    $('#product-input-3').submit()
    $('#target-iframe').ready ->
        app.views.imageselect.render(item_id)

This is predicated on the idea that calling 'submit' immediately puts the target iframe into non-ready state, which seems reasonable, but I'd test it. 这是基于调用'submit'立即将目标iframe置于非就绪状态的想法,这似乎是合理的,但我会测试它。 Once it finishes loading The other option I've seen around is to have the page the iframe loads call back into its parent (top-level) window. 一旦它完成加载我见过的另一个选项是让iframe加载回调到其父(顶级)窗口的页面。 In JS, something like: 在JS中,类似于:

parent.imageUploaded()

Or, if you want to use bound events: 或者,如果要使用绑定事件:

parent.$(parent.document).trigger('upload-complete')

Where, of course, you've set up an upload-complete event on the top-level document object. 当然,您已在顶级文档对象上设置了upload-complete事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM