【问题标题】:Events of $.ajax, how to create a callback?$.ajax 的事件,如何创建回调?
【发布时间】:2011-11-27 11:19:50
【问题描述】:

我知道标题不是很直观,所以我将尝试详细说明我的问题:

我正在创建一个 jQuery 插件来进行异步调用。 有了它,我可以例如使用以下命令发帖:

$("form").bindAjaxPost "post"

问题是我想为这些事件(beforeSendcompletesuccesserror)创建回调,例如,命令看起来像:

$("form").bindAjaxPost "post", 
    success: (data) -> console.log "user success #{data}"
    beforeSend: () -> console.log "user beforeSend"

请注意,事件 beforeSendsuccess 是由插件用户定义的,并且也在插件代码内部:参见代码:

方法后 jquery 插件

post: (ajaxUserOptions)-> 

    ajaxOptions = 
        type: "POST"
        url: @options.url
        data: $(@form).serialize()
        dataType: @options.dataType

        beforeSend: ->
            console.log "plugin beforeSend"

        complete: ->
            console.log "plugin complete"

        success: (data) ->
            console.log "plugin success"

        error: (request) ->
            console.log "plugin error"


    ajaxOptions = $.extend {}, ajaxUserOptions, ajaxOptions if ajaxUserOptions
    $.ajax(ajaxOptions)

问题

我想事件成功,应该在内部调用,然后是用户自定义事件插件。 (这个顺序)

执行示例

命令

$("form").bindAjaxPost "post", 
    success: (data) -> console.log "user success #{data}"
    beforeSend: () -> console.log "user beforeSend"

输出

发送前插件 用户之前发送 插件成功 用户成功

尝试

正如您在代码中看到的,我尝试使用 jQuery 的命令extend。但它不起作用,因为$.ajax().beforeSend 只接受一个函数。

我也尝试访问ajaxUserOptions,但ajaxUserOptions 在事件successbeforeSend...中不可用,因为这些调用是异步的。

感谢大家的帮助!

【问题讨论】:

    标签: jquery jquery-plugins coffeescript


    【解决方案1】:

    您可能会发现使用在 jQuery 1.5 中添加到 $.ajax 的返回值的 Promise 接口更容易实现。这样,您可以附加多个 completesuccesserror 回调(最好是 alwaysdonefail,因为以前的名称将在 jQuery 1.8 中被弃用。)所以你的代码可能会变成

        post: (ajaxUserOptions = {}) -> 
    
            defaultAjaxOptions =
                type: "POST"
                url: @options.url
                data: $(@form).serialize()
                dataType: @options.dataType
    
            jqXHR = $.ajax($.extend {}, ajaxUserOptions, defaultAjaxOptions)
            jqXHR.always pluginAlways
            jqXHR.always ajaxUserOptions.always if ajaxUserOptions.always
            # and likewise for fail and done
    

    beforeSend 是一个更棘手的情况,因为您不能在 jqXHR 对象上执行此操作,但这只是将插件函数和用户函数包装在一个函数中的问题,如果其中任何一个函数返回 false ,外部函数会这样做(因为这会停止 Ajax 请求):

    beforeSend = ->
      return false if pluginBeforeSend() is false
      return false if ajaxUserOptions?.beforeSend() is false
    

    【讨论】:

    • 我会研究Promise interface。关于beforeSend 事件。问题是我无权访问对象ajaxUserOptions。因为调用是异步的,所以对象ajaxUserOptions只能在post方法中使用。
    • 对,我建议在post 方法中定义beforeSend 包装器并将其添加到传递给$.ajax 的对象中。
    【解决方案2】:

    如果存在,您能否从插件内部调用用户提供的回调?类似这样:

    post: (ajaxUserOptions)-> 
    
      ajaxOptions = 
        type: "POST"
        url: @options.url
        data: $(@form).serialize()
        dataType: @options.dataType
    
        beforeSend: ->
          console.log "plugin beforeSend"
          ajaxUserOptions.beforeSend() if ajaxUserOptions?.beforeSend?
    
        complete: ->
          console.log "plugin complete"
    
        success: (data) ->
          console.log "plugin success"
          ajaxUserOptions.success(data) if ajaxUserOptions?.success?
    
        error: (request) ->
          console.log "plugin error"
    
        $.ajax(ajaxOptions)
    

    【讨论】:

    • 是的,我试过了。请参阅问题,我在其中谈论我的尝试。问题是我无权访问对象 ajaxUserOptions。因为调用是异步的,所以对象ajaxUserOptions只能在post方法中使用。
    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多