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