1
 27

Responder

Objective
  • Responder

Une instance de Responder envoie automatiquement des messages de notification à une ou plusieurs instances. Des instances de Responder peuvent être reliées afin que les notifications soient automatiquement transmises d'un répondeur à un autre.

  1. function Responder() {
  2. }
  3.  
  4. Responder.prototype = Object.create(Objective.prototype);
  5.  
  6. Object.defineProperty(Responder.prototype, 'constructor', { value: Responder, enumerable: false, writable: true });

Une instance de Responder hérite de la classe Objective.

  1. Object.defineProperty(Responder.prototype, 'nextResponders', {
  2.     get:    function() {
  3.         return this._nextResponders || null;
  4.     },
  5.     set:    function(responders) {
  6.         if (! (responders === null || (Array.isArray(responders) && responders.every((r) => r instanceof Responder))))
  7.             throw new TypeError();
  8.  
  9.         this._nextResponders = responders;
  10.     }
  11. });

L'accesseur nextResponders retourne la liste des répondeurs de this dans un tableau ou initialise la liste des répondeurs de this avec le tableau responders. IMPORTANT : nextResponders ne fait pas de copie.

  1. Responder.prototype.addNextResponder = function(r) {
  2.     if (!( r instanceof Responder))
  3.         throw new TypeError();
  4.  
  5.     if (! this._nextResponders)
  6.         this._nextResponders = [r];
  7.     else if (this._nextResponders.indexOf(r) == -1)
  8.         this._nextResponders.push(r);
  9.  
  10.     return this;
  11. };

addNextResponder ajoute r à la liste des répondeurs de this.

  1. Responder.prototype.removeNextResponder = function(r) {
  2.     if (this._nextResponders) {
  3.         let i = this._nextResponders.indexOf(r);
  4.  
  5.         if (i != -1)
  6.             this._nextResponders.splice(i, 1);
  7.     }
  8.  
  9.     return this;
  10. };

removeNextResponder retire r de la liste des répondeurs de this.

  1. Responder.prototype.respondTo = function(f, ...args) {
  2.     if (typeof this[f] === 'function' && this[f](...args))
  3.         return this;
  4.  
  5.     if (! this._nextResponders)
  6.         return this;
  7.  
  8.     for (let r of this._nextResponders)
  9.         r.respondTo(f, ...args);
  10.  
  11.     return this;
  12. };

Si this a la méthode f, respondTo exécute f de this avec args. Si this n'a pas la méthode f ou si l'exécution de f de this retourne false, respondTo transmet l'exécution de f avec args à toutes les instances dans la liste des répondeurs de this.

  1. Responder.prototype.nextRespondTo = function(f, ...args) {
  2.     if (this._nextResponders)
  3.         for (let r of this._nextResponders)
  4.             r.respondTo(f, ...args);
  5.  
  6.     return this;
  7. };

nextRespondTo transmet directement l'exécution de f avec args à toutes les instances dans la liste des répondeurs de this.

Test
  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Responder.js'); ?>

Ajoute les balises <script src="/objectivejs/Objective.js"></script> et <script src="/objectivejs/Responder.js"></script> dans la section <head> du document HTML.

  1. function X() {
  2.     Responder.call(this);
  3. }
  4.  
  5. X.prototype = Object.create(Responder.prototype);
  6.  
  7. Object.defineProperty(X.prototype, 'constructor', { value: X, enumerable: false, writable: true });
  8.  
  9. X.prototype.click = function() {
  10.     console.log('X clicked');
  11.  
  12.     this.respondTo('clicked', this);
  13. }
  14.  
  15. X.prototype.clicked = function(sender) {
  16.     console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
  17.  
  18.     return false;
  19. }

Une instance de X est un Responder. La méthode click affiche un message de trace sur la console et notifie clicked à this avec this comme paramètre, i.e. comme expéditeur de la notification. La méthode clicked capture la notification clicked, affiche un message de trace sur la console et retourne false afin de transmettre clicked à tous les répondeurs de this.

  1. function Y() {
  2.     Responder.call(this);
  3. }
  4.  
  5. Y.prototype = Object.create(Responder.prototype);
  6.  
  7. Object.defineProperty(Y.prototype, 'constructor', { value: Y, enumerable: false, writable: true });
  8.  
  9. Y.prototype.clicked = function(sender) {
  10.     console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
  11.  
  12.     return true;
  13. }

Une instance de Y est un Responder. La méthode click affiche un message de trace sur la console et notifie clicked à this avec this comme paramètre, i.e. comme expéditeur de la notification. La méthode clicked capture la notification clicked, affiche un message de trace sur la console et retourne true afin de ne pas transmettre clicked à tous les répondeurs de this.

  1. function Z() {
  2.     Responder.call(this);
  3. }
  4.  
  5. Z.prototype = Object.create(Responder.prototype);
  6.  
  7. Object.defineProperty(Z.prototype, 'constructor', { value: Z, enumerable: false, writable: true });
  8.  
  9. Z.prototype.clicked = function(sender) {
  10.     console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
  11.  
  12.     return true;
  13. }

Une instance de Z est un Responder. La méthode click affiche un message de trace sur la console et notifie clicked à this avec this comme paramètre, i.e. comme expéditeur de la notification. La méthode clicked capture la notification clicked, affiche un message de trace sur la console et retourne true afin de ne pas transmettre clicked à tous les répondeurs de this.

  1. var x = new X();
  2. var y = new Y();
  3. var z = new Z();

Crée une instance de X, de Y et de Z.

  1. x.click();

Clique x qui affiche X clicked puis répond au message clicked en affichant X received a click from X.

  1. x.addNextResponder(y);
  2. x.click();

Ajoute y à la liste des répondeurs de x. Clique x qui affiche X clicked, répond au message clicked en affichant X received a click from X, puis retransmet le message clicked à y qui affiche Y received a click from X.

  1. delete X.prototype.clicked;
  2. x.click();

Supprime la méthode clicked de la classe X. Clique x qui affiche X clicked puis retransmet le message clicked à y qui affiche Y received a click from X.

  1. x.addNextResponder(z);
  2. let responders = x.nextResponders;
  3. for (let r of responders)
  4.     console.log(r.constructor.name);
  5. x.nextResponders = null;
  6. console.log(x.nextResponders);
  7. x.nextResponders = responders;

Ajoute z à la liste des répondeurs de x. Affiche le nom de la classe de tous les répondeurs de x. Vide la liste des répondeurs de x et l'affiche, i.e. null. Rétablit la liste des répondeurs de x.

  1. x.click();

Clique x qui affiche X clicked et retransmet le message clicked à y qui affiche Y received a click from X et à z qui affiche Z received a click from X .

  1. x.removeNextResponder(y);
  2. x.click();

Retire y de la liste des répondeurs de x. Clique x qui affiche X clicked et retransmet le message clicked à z qui affiche Z received a click from X .

  1. z.addNextResponder(y);
  2. x.click();

Ajoute y à la liste des répondeurs de z. Clique x qui affiche X clicked et retransmet le message clicked à z qui affiche Z received a click from X et ne le retransmet pas à y.

Affichez la page générée par le fichier testResponder.phtml et vérifiez la trace dans la console du navigateur :

X clicked
X received a click from X
X clicked
X received a click from X
Y received a click from X
X clicked
Y received a click from X
Y
Z
null
X clicked
Y received a click from X
Z received a click from X
X clicked
Z received a click from X
X clicked
Z received a click from X

Modifiez la méthode clicked de la classe Z pour qu'elle retourne false au lieu de true et rechargez la page de test.

...
X clicked
Z received a click from X
Y received a click from X

z affiche Z received a click from X et retransmet le message clicked à y qui affiche Y received a click from X.

VOIR AUSSI

Objective, View

Commentaires

Votre commentaire :
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip aide 2000

Entrez un maximum de 2000 caractères.
Améliorez la présentation de votre texte avec les balises de formatage suivantes :
[p]paragraphe[/p], [b]gras[/b], [i]italique[/i], [u]souligné[/u], [s]barré[/s], [quote]citation[/quote], [pre]tel quel[/pre], [br]à la ligne,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]commande[/code], [code=langage]code source en c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].