Reputation: 99
This is a general question about javascript. What I want to achieve but I don't know if it's possible is the following.
I want to write a javascript library that contains an object. So by using this javascript library I want to instanciate the object from another javascript file by doing:
myObject = new myObject();
I achieved that by writing a function in my javascript library:
function myObject() {
//init object logic
}
The thing is that now I want to be able to listen to different events of that object from the javascript file where I instansciated the object before. something like:
myObject = new myObject();
myObject.on('connection', function(conn) {
conn.on('data', function(data){
console.log("conn on data");
});
conn.on('error', function(data){
console.log("conn on error");
});
});
How can I achieve this in javascript? I was thinking about callbacks but I can't figure out the way.
Upvotes: 0
Views: 651
Reputation: 69
//library
function myObject() {
//init object logic
}
myObject.prototype.attach=function(eventType,callBack){
//default event
document.addEventListener(eventType,callBack);
......
//custom event code
var event = new Event('connection');
// Listen for the event.
document.addEventListener('connection', function (e) { ... }, false);
}
//userFile
myObject = new myObject();
myObject.attach("click",clikeMe);
function clickMe(eventObject){
.......
......
}
// to dispatch custom event
document.dispatchEvent(event)
Upvotes: 1
Reputation: 7285
You're looking for a EventEmitter
which you could implement this way:
class EventEmitter {
constructor () {
this.events = {};
}
on (channel, cb) {
if (Array.isArray(this.events[channel])) {
this.events[channel].push(cb);
} else {
this.events[channel] = [cb];
}
}
emit (channel, ...args) {
if (Array.isArray(this.events[channel])) {
this.events[channel].forEach(cb => cb.apply(null, args));
}
}
}
Your class can inherit from EventEmitter
:
class MyClass extends EventEmitter {
constructor () {
super();
// do initialization
}
}
And now, you can instantiate your class:
var myObject = new MyClass();
myObject.on('event', function (a, b) {
console.log('Event A was emitted: ', a + b);
});
myObject.emit('event', 123, 456); // "Event A was emitted: 579"
Working example:
class EventEmitter {
constructor () {
this.events = {};
}
on (channel, cb) {
if (Array.isArray(this.events[channel])) {
this.events[channel].push(cb);
} else {
this.events[channel] = [cb];
}
}
emit (channel, ...args) {
if (Array.isArray(this.events[channel])) {
this.events[channel].forEach(cb => cb.apply(null, args));
}
}
}
class MyClass extends EventEmitter {
constructor () {
super();
// do initialization
}
}
var myObject = new MyClass();
myObject.on('event', function (a, b) {
console.log('Event A was emitted: ', a + b);
});
myObject.emit('event', 123, 456); // "Event A was emitted: 579"
Note that I used a few new features, for example the spread operator (...
) and the new class
syntax. Of course, you can also achieve the same using the old function
and prototype
way.
In your code, you have the line
myObject = new myObject();
Don't do that. You assign the new instance to the variable that contains the constructor, losing access to that constructor.
NodeJS has its own EventEmitter
class. You can access it using:
var EventEmitter = require('events').EventEmitter;
Upvotes: 3