Question

Nous n'utilisons actuellement aucun cadre côté client sérieux en plus jQuery (et jQuery.UI + Validation + Form Plugins Assistant).

Un problème qui fait surface plusieurs fois dans notre code est le suivant:

  1. Nous avons un bouton qui initie un appel ajax au serveur.
  2. Pendant que l'appel a lieu, nous affichons une icône de "chargement" avec du texte
  3. Si le serveur renvoie un résultat trop rapidement (par exemple <200 ms), nous «dormons» pour 200 millis (en utilisant setTimeout()), Pour éviter le scintillement de l'icône d'attente et du texte.
  4. Après max(the call returns, a minimal timeout), nous effacons l'icône de chargement et le texte.
  5. Nous affichons ensuite un texte d'erreur, s'il y avait un problème dans l'appel AJAX (le serveur ne renvoie pas 500, mais un JSON personnalisé qui a une propriété "Message d'erreur". En fait, nous avons parfois une telle propriété dans le Réponse par champ de formulaire ... et nous correspondons ensuite aux erreurs pour former des champs ... mais je m'éloigne).
  6. En cas de succès, nous le faisons ... quelque chose (dépend de la situation).

J'essaie de minimiser la réutilisation du code, et d'écrire ou de réutiliser un motif / morceau de code / framework qui le fait. Bien que je ne commence pas probablement à utiliser un tout nouveau cadre lourd pour ce cas d'utilisation, je voudrais toujours savoir quelles sont mes options ... peut-être qu'un tel cadre côté client serait également bon pour d'autres choses. S'il y a un cadre léger qui ne vous oblige pas à refuser tout mon code, et je pourrais utiliser uniquement sur des cas spécifiques, alors nous pourrions réellement l'utiliser au lieu de réinventer la roue.

J'ai récemment entendu parler Ember.js - Est-ce un bon choix pour résoudre ce problème? Comment le résoudriez-vous?

Était-ce utile?

La solution

$(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);
});

Autres conseils

Enveloppez simplement le $ .ajax dans votre propre fonction. De cette façon, vous pouvez mettre en œuvre votre propre exigence, etc. Je suggère de faire un composant jQuery pour cela. Il peut devenir assez puissant, par exemple, vous pouvez également passer des en-têtes HTTP, etc.
En ce qui concerne les cadres, cela dépend de vos exigences.
Par exemple, vous pouvez considérer Kendo UI, il a un bon cadre pour créer des sources de données:http://demos.kendoui.com/web/datasource/index.html.

Exemple de code de travail (enfin, presque)

J'allais pour quelque chose dans le sens de la réponse de @ defygravity de toute façon - son idée est bonne, mais est toujours un pseudo-code / pas complètement complet. Voici mon code de travail (Demo qui fonctionne presque, jusqu'à l'URL Ajax lui-même, et les ajustements d'interface utilisateur)

Le code et l'exemple d'utilisation:

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");
    });
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top