Responder
- Responder
An instance of Responder automatically sends notification messages to one or several instances. Responder instances can be linked so notifications are automatically transmitted from one responder to another.
- function Responder() {
- }
- Responder.prototype = Object.create(Objective.prototype);
- Object.defineProperty(Responder.prototype, 'constructor', { value: Responder, enumerable: false, writable: true });
An instance of Responder inherits from the class 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;
- }
- });
The accessor nextResponders returns the list of responders of this in an array or initializes the list of responders of this with the array responders.
IMPORTANT: nextResponders doesn't make a copy.
- 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 adds r to the list of responders of 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 removes r from the list of responders of 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;
- };
If this has the method f, respondTo executes f of this with args.
If this doesn't have the method f or if the execution of f of this returns false, respondTo transmits the execution of f with args to all the instances in the list of responders of this.
- Responder.prototype.nextRespondTo = function(f, ...args) {
- if (this._nextResponders)
- for (let r of this._nextResponders)
- r.respondTo(f, ...args);
- return this;
- };
nextRespondTo directly transmits the execution of f with args to all the instances in the list of responders of this.
Test
- <?php head('javascript', '/objectivejs/Objective.js'); ?>
- <?php head('javascript', '/objectivejs/Responder.js'); ?>
Adds the tags <script src="/objectivejs/Objective.js"></script> and <script src="/objectivejs/Responder.js"></script> to the <head> section of the HTML document.
- 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;
- }
An instance of X is a Responder.
The click method displays a trace message on the console and notifies clicked to this with this as a parameter, i.e. as the sender of the notification.
The clicked method captures the clicked notification, displays a trace message on the console and returns false in order to transmit clicked to all the responders of 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;
- }
An instance of Y is a Responder.
The click method displays a trace message on the console and notifies clicked to this with this as a parameter, i.e. as the sender of the notification.
The clicked method captures the clicked notification, displays a trace message on the console and returns true in order to not transmit clicked to all the responders of 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;
- }
An instance of Z is a Responder.
The click method displays a trace message on the console and notifies clicked to this with this as a parameter, i.e. as the sender of the notification.
The clicked method captures the clicked notification, displays a trace message on the console and returns true in order to not transmit clicked to all the responders of this.
- var x = new X();
- var y = new Y();
- var z = new Z();
Creates an instance of X, of Y and of Z.
- x.click();
Clicks x which displays X clicked then responds to the message clicked by displaying X received a click from X.
- x.addNextResponder(y);
- x.click();
Adds y to the list of responders of x.
Clicks x which displays X clicked, responds to the message clicked by displaying X received a click from X, then transmits the message clicked to y which displays Y received a click from X.
- delete X.prototype.clicked;
- x.click();
Removes the method clicked from the class X.
Clicks x which displays X clicked then transmits the message clicked to y which displays 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;
Adds y to the list of responders of x.
Displays the name of the class of all the responders of x.
Empties the list of responders of x and displays it, i.e. null.
Restores the list of responders of x.
- x.click();
Clicks x which displays X clicked and transmits the message clicked to y which displays Y received a click from X and to z which displays Z received a click from X.
- x.removeNextResponder(y);
- x.click();
Removes y from the list of responders of x.
Clicks x which displays X clicked and transmits the message clicked to z which displays Z received a click from X.
- z.addNextResponder(y);
- x.click();
Adds y to the list of responders of z.
Clicks x which displays X clicked and transmits the message clicked to z which displays Z received a click from X and doesn't transmit it to y.
Display the page generated by the file testResponder.phtml and check the trace in the console of the browser:
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
Modify the clicked method of the class Z so it returns false instead of true and reload the test page.
...
X clicked
Z received a click from X
Y received a click from X
z displays Z received a click from X and transmits the message clicked to y which displays Y received a click from X.
Comments