jQuery When Done on dynamically pulled function ca

2019-09-04 12:18发布

问题:

I have the following code:

In site-code.js

....

var ajaxContentFunc = $(origin).data("modal-content-handler");

$.when(window[ajaxContentFunc]()).done(function (resp) {
    kModal.showContent(resp);
});

In another file I have the following tag and function

<a href="#" data-modal-content-handler="ajaxContentGeneration">Click Me</a>

....

function ajaxContentGeneration() {

    var aProm = $.ajax({

        url: "tests/ajax/AjaxTest.aspx",
        data: { exampleType: "modal-ajax" },
        dataType: "html"


    });


    aProm.done(function (data) {

        console.log("Ajax Loaded!");
        var content = $(data).find("#ajax-content");

        return aProm;

    });


}

I need to populate the result of the ajaxContentGeneration (whatever method that might be) into the variable to send to showContent or in other words:

1) Pull the ajaxContentFunction Name from the tag's modal-content-handler data attribute

2) Call function (in this case ajaxContentGeneration)

3) Wait for the function's ajax to complete and return the data generated (in this case html)

4) When completed pass that value to kModal.showContent(----Here----);

However currently I am getting:

1) Pulls ajaxContentFunctionName correctly

2) Calls Function (ajaxContentGeneration() function)

3) Calls kModal.showContent(undefined). This is called prematurely because the deferred isn't correctly waiting for the function call to complete (after the ajax is done).

4) Ajax Completes

Where am I messing up here ?

回答1:

As far as I can tell, you are 95% there.

Use .then() instead of .done() and return the promise returned by $.ajax().then() :

function ajaxContentGeneration() {
    return $.ajax({
        url: "tests/ajax/AjaxTest.aspx",
        data: { exampleType: "modal-ajax" },
        dataType: "html"
    }).then(function (data) {
        return $(data).find("#ajax-content"); // this will return jQuery
        // return $(data).find("#ajax-content").html(); // this will return html
    });
}

You can probably also purge $.when() from the top-level call :

var ajaxContentFunc = $(origin).data("modal-content-handler");
window[ajaxContentFunc]().then(function (resp) {
    // `resp` is whatever was returned by the `return $(data).find()...` statement above
    kModal.showContent(resp);
});

The reason I say "probably" is that $.when() would be necessary if value-returning (not promise-returning) functions could be called instead of ajaxContentGeneration().



回答2:

Another way would be to do:

// should really be renamed...
function ajaxContentGeneration(){
    return $.ajax({
        url      : "tests/ajax/AjaxTest.aspx",
        data     : { exampleType: "modal-ajax" },
        dataType : "html"
    })
}

Somewhere else:

var ajaxContentFunc = $(origin).data("modal-content-handler");

window[ajaxContentFunc]()
    .done(function(RES){
        kModal.showContent( $(RES).find("#ajax-content") );
    });

So the functionality of the ajaxContentGeneration function will be to return an AJAX promise, and not have it manipulated inside it, but do the manipulation where needed (getting the #ajax-content element from the response)


Note that this whole thing is bad practice JS design, and you should avoid having functions on top of the window object, but instead on another object.