1

複数のAJAX呼び出しがあるステートメントにAJAXロードインジケーターを挿入する最良の方法は何ですか?

例えば:

$("#search_building").on("change blur", function () {
    var building = $("#search_building").val();
    var room = $("#search_room").val();
    var dept = $("#dept").val();
    var dataString = 'room=' + room + '&' + 'building=' + building + '&' + 'dept=' + dept;
    $.ajax({
        type: "POST",
        url: "process_building.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#search_room').html(html);
        }
    });
    $.ajax({
        type: "POST",
        url: "process_timetableMon.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#grid2_mon').html(html);
        }
    });
         $.ajax({
        type: "POST",
        url: "process_timetableTue.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#grid2_tue').html(html);
        }
    });
        $.ajax({
        type: "POST",
        url: "process_timetableWed.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#grid2_wed').html(html);
        }
    });
        $.ajax({
        type: "POST",
        url: "process_timetableFri.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#grid2_wed').html(html);
        }
    });
        $.ajax({
        type: "POST",
        url: "process_roomList.php",
        data: dataString,
        cache: false,
        success: function (html) {
            $('#list2').html(html);
        }
    });
        }); 
4

3 に答える 3

2

私のブログから:

カウンターやその他の標準以下のアプローチを使用すると、コードベースがますます読みにくくなり、保守が難しくなるため、コードの機能不全が助長されます。これを達成するための理想的な方法は、イベント駆動型アプローチを使用することです。保守が容易になり、今後のスパゲッティ コードの削減につながります。次のようなものを簡単に実装できます。

//First, we need an object that will contain our 'event domain'
var EventDomain = new function(config,callback){

this.__listeners = {}; //this will store references to functions associated to events

this.on = function(event,listener){ //here, we provide a member that binds 
                                    //a 'listener' function to an event string
    if (typeof this.__listeners[event] == "undefined"){
        this.__listeners[event] = [];
    }
    this.__listeners[event].push(listener);
};
this.emit = function(event,params){ //here, we provide a member that 'emits' an
                                    //event string, calling any 'listener' functions
                                    //and passing a parameter object 
                                    //{param1: val1, param2:val2, paramN, valN} 
    if(typeof event == "string"){
        event = { type: event };
    }
    if(!event.target){
        event.target = this;
    }

    if(!event.type){
        throw new Error("Event object missing 'type' property.");
    }
    if(this.__listeners[event.type] instanceof Array){
        var listeners = this.__listeners[event.type];
        for (var i=0, len=listeners.length; i < len; i++){
            listeners[i](params);
        }
    }
};
this.removeListener = function(type, listener){ //here, we provide a member that allows
                                                //us to remove a 'listener' function 
                                                //from an event
    if(this.__listeners[type] instanceof Array){
        var listeners = this.__listeners[type];
        for (var i=0, len=listeners.length; i < len; i++){
            if (listeners[i] === listener){
                listeners.splice(i, 1);
                break;
            }
        }
    }
};
this.removeAllListeners = function(type){ //here, we provide a member that allows
                                          //us to remove ALL 'listener' functions
                                          //from an event
    if(this.__listeners[type] instanceof Array){
        delete this.__listeners[type];
    }
};
};

イベント ドメインができたので、それを上記のコード スニペットで使用できます。しかし、最初に、ajax 呼び出しのコントローラーとして機能するオブジェクトを作成しましょう。

var AjaxController = new function(){  
    var counter;  //create a private member called counter
    this.onLoad = function(fn){ //here, we provide a member to specify what to do
                                //when ajax requests begin
        EventEmitter.on('ajax_loading',(function(fn){ //bind 'ajax_loading' event to an  
                                                      //ajax loading indicator
            return function(){ //yet another closure
                if(counter<1){ //obviously, we only want to do something on the first
                               //load, not every single time.  Otherwise, you'll end
                               //end up trying to show the exact same loading animation
                               //for each ajax call
                    fn();
                }
                counter++;
            };
        })(fn));
    };

    this.onComplete = function(fn){ //here we provide a member to specify what to do
                                    //when ALL ajax requests have finished
        EventEmitter.on('ajax_complete',(function(fn){ //bind the 'ajax_complete' event 
                                                       //to a loading indicator
            return function(){ //yet another closure
                counter--; //decrement concurrent loading
                if(counter<1){ //its only finished once the counter is 0!
                   fn();
                }
            }
        })(fn));
    };

    var constructor = function(){ //good object oriented programming uses constructors!
        counter = 0;
        //Now, lets overload the original $.ajax method to provide functionality
        //for our event driven approach
        $.ajax = (function(ajax){ //this is called a 'closure'.  
                                  //We pass it the original function and it wraps and 
                                  //returns it, overloading the original method                                       
            function overloadAjax(params){ //this is our overloading function
                  if(params.success){ //if there is a success parameter passed
                                      //to the ajax call, overload that as well
                                      //to emit the 'ajax_complete' event
                     params.success = (function(success){
                         function overloadSuccess(data){
                             EventDomain.emit('ajax_complete');
                             success(data);
                         }
                         return overloadSuccess; //return and overload success
                     })(params.success);
                  }
                  EventDomain.emit('ajax_loading'); //emit the 'ajax_loading' event
                                                    //for each ajax call
                  ajax(params);
            }
            return overloadAjax; //here we return 'overload' back to $.ajax, overloading       
                                 //the original
        })($.ajax);


    }
    constructor(); //we call the constructor after all members have been prototyped 
}

再利用可能な素敵な ajax ローダー ツールキットを作成したので、それを使用してみましょう。

AjaxController.onLoad(function(){
   //put some code here to do DOM manipulation to add a loader, or however you
   //want to 'indicate' ajax loading
});

AjaxController.onComplete(function(){
   //put some code here to do some DOM manipulation to remove your loader, or however
   //you want to 'indicate' that ajax loading is complete
});

今、それはうまくいきます:

$("#search_building").on("change blur", function () {

var building = $("#search_building").val();
var room = $("#search_room").val();
var dept = $("#dept").val();
var dataString = 'room=' + room + '&' + 'building=' + building + '&' + 'dept=' + dept;
$.ajax({
    type: "POST",
    url: "process_building.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#search_room').html(html);
    }
});
$.ajax({
    type: "POST",
    url: "process_timetableMon.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#grid2_mon').html(html);
    }
});
     $.ajax({
    type: "POST",
    url: "process_timetableTue.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#grid2_tue').html(html);
    }
});
    $.ajax({
    type: "POST",
    url: "process_timetableWed.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#grid2_wed').html(html);
    }
});
    $.ajax({
    type: "POST",
    url: "process_timetableFri.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#grid2_wed').html(html);
    }
});
    $.ajax({
    type: "POST",
    url: "process_roomList.php",
    data: dataString,
    cache: false,
    success: function (html) {
        $('#list2').html(html);
    }
});
    }); 

フロントエンドでイベント駆動型プログラミングとオブジェクト指向プログラミングを組み合わせることの大きな利点は、開発者がより実際のコンテンツ作成に専念でき、問題解決が少なくなることです。再利用可能なフレームワークを作成するには、最初は時間がかかりますが、時間と品質の面で飛躍的なメリットがあります。これらの概念についてさらにサポートが必要な場合は、お気軽にメールでお問い合わせください: rhyneandrew@gmail.com. 無料で教えていただけると嬉しいです(;_;)

于 2013-02-17T05:18:02.463 に答える
0

カウンターを使用して、進行中のAJAXリクエストの数を記録できます。カウンターが1より大きい場合は、ローディングインジケーターを表示します。応答を受け取るたびに、1ずつデクリメントします。カウンターが0に達したら、ロードインジケーターを非表示にします。

于 2013-02-17T04:18:42.657 に答える
0

$.ajax()呼び出しで次のようなものを使用できます。

$.ajaxSetup({
    beforeSend:function(){
        // show image here
        $("#busy").show();
    },
    complete:function(){
        // hide image here
        $("#busy").hide();
    }
});
于 2013-02-17T04:25:17.483 に答える