Responder
- 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.
- function Responder() {
- }
- Responder.prototype = Object.create(Objective.prototype);
- Object.defineProperty(Responder.prototype, 'constructor', { value: Responder, enumerable: false, writable: true });
Une instance de Responder hérite de la classe Objective.
- Object.defineProperty(Responder.prototype, 'nextResponders', {
- get: function() {
- return this._nextResponders || null;
- },
- set: function(responders) {
- if (! (responders === null || (Array.isArray(responders) && responders.every((r) => r instanceof Responder))))
- throw new TypeError();
- this._nextResponders = responders;
- }
- });
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.
- Responder.prototype.addNextResponder = function(r) {
- if (!( r instanceof Responder))
- throw new TypeError();
- if (! this._nextResponders)
- this._nextResponders = [r];
- else if (this._nextResponders.indexOf(r) == -1)
- this._nextResponders.push(r);
- return this;
- };
addNextResponder
ajoute r
à la liste des répondeurs de this
.
- Responder.prototype.removeNextResponder = function(r) {
- if (this._nextResponders) {
- let i = this._nextResponders.indexOf(r);
- if (i != -1)
- this._nextResponders.splice(i, 1);
- }
- return this;
- };
removeNextResponder
retire r
de la liste des répondeurs de this
.
- Responder.prototype.respondTo = function(f, ...args) {
- if (typeof this[f] === 'function' && this[f](...args))
- return this;
- if (! this._nextResponders)
- return this;
- for (let r of this._nextResponders)
- r.respondTo(f, ...args);
- return this;
- };
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
.
- Responder.prototype.nextRespondTo = function(f, ...args) {
- if (this._nextResponders)
- for (let r of this._nextResponders)
- r.respondTo(f, ...args);
- return this;
- };
nextRespondTo
transmet directement l'exécution de f
avec args
à toutes les instances dans la liste des répondeurs de this
.
Test
- <?php head('javascript', '/objectivejs/Objective.js'); ?>
- <?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.
- function X() {
- Responder.call(this);
- }
- X.prototype = Object.create(Responder.prototype);
- Object.defineProperty(X.prototype, 'constructor', { value: X, enumerable: false, writable: true });
- X.prototype.click = function() {
- console.log('X clicked');
- this.respondTo('clicked', this);
- }
- X.prototype.clicked = function(sender) {
- console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
- return false;
- }
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
.
- function Y() {
- Responder.call(this);
- }
- Y.prototype = Object.create(Responder.prototype);
- Object.defineProperty(Y.prototype, 'constructor', { value: Y, enumerable: false, writable: true });
- Y.prototype.clicked = function(sender) {
- console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
- return true;
- }
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
.
- function Z() {
- Responder.call(this);
- }
- Z.prototype = Object.create(Responder.prototype);
- Object.defineProperty(Z.prototype, 'constructor', { value: Z, enumerable: false, writable: true });
- Z.prototype.clicked = function(sender) {
- console.log(this.constructor.name + ' received a click from ' + sender.constructor.name);
- return true;
- }
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
.
- var x = new X();
- var y = new Y();
- var z = new Z();
Crée une instance de X, de Y et de Z.
- x.click();
Clique x
qui affiche X clicked
puis répond au message clicked en affichant X received a click from X
.
- x.addNextResponder(y);
- 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
.
- delete X.prototype.clicked;
- 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
.
- x.addNextResponder(z);
- let responders = x.nextResponders;
- for (let r of responders)
- console.log(r.constructor.name);
- x.nextResponders = null;
- console.log(x.nextResponders);
- 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
.
- 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
.
- x.removeNextResponder(y);
- 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
.
- z.addNextResponder(y);
- 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
.
Commentaires