Comment ajouter un message à l'utilisateur avec la fonction sync() de ExtJs

En attendant la version 4.1 de ExtJs qui verra arriver la prise en charge d'un callback dans la fonction sync() de Ext.data.Store. Voici un petit snippet qui vous permettra d'afficher un message à l'utilisateur pour l'informer de la réussite ou de l'erreur renvoyé par le serveur suite à l'appel de la fonction sync().

 

1. Comment ça marche

En regardant la détail de la fonction sync() dans la class Ext.data.AbstractStore on s'apperçoit que ExtJs appelle la fonction batch() de la class Ext.data.proxy.Proxy. Cette dernière fonction fait appel en interne aux classes Ext.data.Operation et Ext.data.Batch
Mais revenons à la fonction sync(). Cette fonction teste s'il y a des Record (instance de la classe Ext.data.Model) à créer, à mettre à jour ou à supprimer. Anisi ExtJs va créer jusqu'a 3 opérations qui seront executées par la classe Batch.
Au moment de passer la liste des opération à faire à la fonction batch() du proxy, ExtJs appelle la fonction getBatchListeners() de la classe AbstractStore. Cette fonction (private) spécifie les listeners qui seront appelés à la fin de chaque opération.  On découvre ainsi qu' après chaque opération ExtJs appelera une des 3 fonctions: onBatchException(), onBatchOperationComplete() ou onBatchComplete().

 

2. Gestion des erreurs

Quand une opération est éxecutée, ExtJs fire l'event de gestion d'erreur quand le serveur retourne autre chose qu'un status 200 OK ou quand le serveur retour une json du type:

 
{
	"success": false
}

Dans ce cas c'est la fonction onBatchException() qui est appelée. Le code de cette dernière est comment dire ?

 
    onBatchException: function(batch, operation) {
        // //decide what to do... could continue with the next operation
        // batch.start();
        //
        // //or retry the last operation
        // batch.retry();
    },

Il suffit donc d'implémenter une fonction onBatchException() dans votre class Store pour avertir l'utilisateur d'un problème.

 
Ext.define("Appli.store.SaisieResultats", {
	extend: 'Ext.data;Store',
	requires: ['Appli.model.SaisieResultat'],
	model: 'Appli.model.SaisieResultat',
 
 
	onBatchException: function(batch, operation) {
		Ext.Msg.alert(	'Erreur', 
			'Une erreur est intervenue.');
 
	    this.callParent(arguments);
	}
});
 

Même si l'on a vu que la fonction onBatchException() ne faisait rien dans la class Ext.data.AbstractStore(), je vous conseil de quand même faire appel au parent pour ne pas casser la compatibilité d'une éventuelle prochaine version.

 

3. Gestion du success

Il y a deux type de gestion du success dans le batch, un qui est appelé quand une opération se termine et un autre quand le batch est un succès.

3.a Success d'une opération

C'est surement cette appel qui est le plus utile. Quand la class Batch termine le traitement d'une Operation et que le serveur retourne un status 200 OK et optionnellement un json de la forme:

 
{
	"success": true
}

ExtJs fait appel à la fonction onBatchOperationComplete().  tout comme pour les erreurs, il suffit de surcharger cette fonction dans votre Store:

 
Ext.define("Appli.store.SaisieResultats", {
	extend: 'Ext.data;Store',
	requires: ['Appli.model.SaisieResultat'],
	model: 'Appli.model.SaisieResultat',
 
 
	onBatchException: function(batch, operation) {
		Ext.Msg.alert(	'Erreur', 
			'Une erreur est intervenue.');
 
	    this.callParent(arguments);
	}
 
	onBatchOperationComplete: function(batch, operation) {
		Ext.Msg.alert(	'Information', 
			'Vos données ont été sauvées.');
 
	    this.callParent(arguments);
	},
});

Mais un problème potentiel persiste suivant  votre application. Dans le cadre de mon application, je ne fais que de la mise à jour de donnée, donc je n'utilise qu'une opération. Si votre application fait plusieurs actions création et/ou mise à jour et/ou suppression, vous aurez autant d'appel à cette fonction que d'opération. Ce qui peut être problèmatique d'afficher 3 messages à l'utilisateur.

 

3.b Success d'un batch

Il existe une dernière fonction onBatchComplete() qui est appelé par ExtJs. Cette fonction est appelé une fois qu'il n'y a plus d'opération à exécuter pour indiquer que le batch est terminé. En théorie, il suffit de la surcharger comme les deux fonctions précédentes pour envoyer à l'utilisateur un message. Je dis en "théorie" car je n'ai jamais réussi à l'appeler dans mes applications, un bug?

 


Tout le code de ce ticket est fonctionnel avec les versions ExtJs 4.0.2 et 4.0.7.

Il y a 2 commentaires

  • olibou06-02-2012 10:22:34

    Et en 4.1, comment doit-on s'y prendre à présent ?

  • Ulrich06-03-2012 15:15:55

    Avec ExtJs version 4.1 c'est beaucoup plus simple. La fonction sync() accepte un objet en option. Cet objet peut contenir un appel spécifique en cas de succès ou d'erreur de la fonction sync(). Il suffit d'utiliser ces options et il n'est plus nécessaire de surcharger la classe native de ExtJs.

    Exemple:

    var monStore = Ext.create('Ext.data.Store,{ ... });
    monStore.sync({
    success: function(batch, options)
    {
    Ext.Msg.alert('Données sauvegardées');
    },
    failure: function(batch, options)
    {
    Ext.Msg.alert('Oups, une erreur s'est produite.');
    }
    });