Frage

Wir verwenden derzeit kein ernsthaftes clientseitiges Framework außer jQuery (und jQuery.ui + Validierung + Formularassistenten-Plugins).

Ein Problem, das in unserem Code einige Male auftritt, ist Folgendes:

  1. Wir haben eine Schaltfläche, die einen Ajax-Aufruf an den Server initiiert.
  2. Während des Anrufs wird ein "Laden" -Symbol mit Text angezeigt
  3. Wenn der Server ein Ergebnis zu schnell zurückgibt (z. B. <200 ms), "schlafen" wir 200 Millis (unter Verwendung von setTimeout()), um ein Flackern des wartenden Symbols und Textes zu verhindern .
  4. Nach dem max(the call returns, a minimal timeout) löschen wir das Ladesymbol und den Text.
  5. Wir zeigen dann entweder einen Fehlertext an, wenn beim Ajax-Aufruf ein Problem aufgetreten ist (der Server gibt nicht 500 zurück, sondern einen benutzerdefinierten JSON mit der Eigenschaft "Fehlermeldung". Tatsächlich haben wir manchmal einen solchen Eigenschaft in der Antwort pro Formularfeld ... und wir ordnen dann Fehler Formularformularen zu ... aber ich schweife ab).
  6. Im Erfolgsfall tun wir ... etwas (abhängig von der Situation).

    Ich versuche, die Wiederverwendung von Code zu minimieren und ein Muster / Code / Framework, das dies tut, entweder zu schreiben oder wiederzuverwenden. Obwohl ich wahrscheinlich nicht nur für diesen Anwendungsfall ein komplett neues Hochleistungs-Framework verwenden werde, würde ich gerne wissen, welche Optionen ich habe ... Vielleicht wäre ein solches clientseitiges Framework auch für andere Dinge gut. Wenn es ein leichtes Framework gibt, bei dem ich nicht meinen gesamten Code auf den Kopf stellen muss und das ich nur in bestimmten Fällen verwenden kann, verwenden wir es möglicherweise tatsächlich, anstatt das Rad neu zu erfinden.

    Ich habe kürzlich von Ember.js gehört - passt es gut zur Lösung dieses Problems? Wie würden Sie es lösen?

War es hilfreich?

Lösung

$(function(){
 var buttonSelector = "#button";
 $('body').on({'click': function(evt){
    var $button = $(this);
    $button.toggleClass('loading');
    var time = new Date();
    $.get('some/ajax').then(function(data,text,jqXhr){
   // typical guess at load work
       $button.empty();
       $(data).wrap($button);
    }).fail(function(data,text,jqXhr){
     alert("failed");
    }).done(function(data,text,jqXhr){
       var elapsed = new Date();
      if((elapsed - time) < 200){
        alert("to short, wait");
      }
      $button.toggleClass('loading');
    });
  }},buttonSelector,null);
});

Andere Tipps

Wickeln Sie einfach die $ .ajax in Ihre eigene Funktion ein.Auf diese Weise können Sie Ihre eigenen Abfragen usw. implementieren. Ich würde vorschlagen, eine jquery-Komponente dafür zu erstellen.Es kann ziemlich mächtig werden, zum Beispiel können Sie auch http-Header usw. übergeben.
In Bezug auf Frameworks hängt es von Ihren Anforderungen ab.
Sie können beispielsweise die Kendo-Benutzeroberfläche in Betracht ziehen. Sie bietet einen guten Rahmen für die Erstellung von Datenquellen: http://demos.kendoui.com/web/datasource/index.html .

Arbeitsbeispielcode (na ja, fast)

Ich habe mich sowieso für etwas entschieden, das der Antwort von @ DefyGravity entspricht - seine Idee ist gut, aber immer noch Pseudocode / nicht vollständig.Hier ist mein Arbeitscode ( fast funktionierende Demo , bis zur Ajax-URL selbst und Verbesserungen an der Benutzeroberfläche)

Das Code- und Verwendungsbeispiel:

jQuery.fn.disable = function() {
    $(this).attr("disabled", "disabled");
    $(this).removeClass("enabled");

    // Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
    $(this).filter("button").button({disabled: true});
};
jQuery.fn.enable = function() {
    $(this).removeAttr("disabled");
    $(this).addClass("enabled");
    // Special handling of jquery-ui buttons: http://stackoverflow.com/questions/3646408/how-can-i-disable-a-button-on-a-jquery-ui-dialog
    $(this).filter("button").button({disabled: false});
};


function AjaxCallbackWaiter(ajaxUrl, button, notificationArea, loadingMessage, errorMessage, inSuccessHandler, inFailureHandler) {
    // Every request that takes less than this, will be intentionally delayed to prevent a flickering effect
    // http://ripper234.com/p/sometimes-a-little-sleep-is-ok/
    var minimalRequestTime = 800;
    var loadingIconUrl = 'http://loadinfo.net/images/preview/11_cyrcle_one_24.gif?1200916238';

    var loadingImageContent = $("<img class='loading-image small' src='" + loadingIconUrl + "'/><span class='loading-text'>" + loadingMessage + "</span>");
    var errorContentTemplate = $("<span class='error ajax-errors'></span>");

    var requestSentTime = null;

    button.click(clickHandler);

    function displayLoadingMessage() {
        clearNotificationArea();
        notificationArea.html(loadingImageContent);
    }

    function clearNotificationArea() {
        notificationArea.html("");
    }

    function displayError(message) {
        var errorContent = errorContentTemplate.clone(errorContentTemplate).html(message);
        notificationArea.html(errorContent);
    }

    function ajaxHandler(result) {
        var requestReceivedTime = new Date().getTime();
        var timeElapsed = requestReceivedTime - requestSentTime;
        // Reset requestSentTime, preparing it for the next request
        requestSentTime = null;

        var sleepTime = Math.max(0, minimalRequestTime - timeElapsed);

        function action() {
            clearNotificationArea();
            button.enable();
            if (result) {
                inSuccessHandler();
            } else {
                displayError(errorMessage);
                inFailureHandler();
            }
        }

        if (sleepTime <= 0) {
            action();
        } else {
            setTimeout(action, sleepTime);
        }
    }

    function failureHandler() {

    }

    function clickHandler(){
        if (requestSentTime !== null) {
            logError("Bad state, expected null");
        }
        requestSentTime = new Date().getTime();
        displayLoadingMessage();
        button.disable();
        $.get(ajaxUrl, 'json').then(ajaxHandler, failureHandler);
    }
}

// Usage:
var ajaxUrl = 'FILL IN YOUR OWN URL HERE';
var button = $("#clickme");
var notificationArea = $(".ajax-notification-area");

var waitingMessage = "Doing Stuff";
var errorMessage = "Not Good<br/> Please try again";

$(document).ready(function(){
  new AjaxCallbackWaiter(
    ajaxUrl,
    button, 
    notificationArea,
    waitingMessage,
    errorMessage,
    function(){
      alert("All is well with the world");
    },
    function(){
      alert("Not good - winter is coming");
    });
});

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top