5

I have a custom object in JavaScript:

function Graph (dataType, provider){
   this.dataType = dataType;
   this.provider = provider;
}

I instantiate this object via "new" and then pass it to other parts of my code that may need to keep track of changes to this object's properties.

When the properties of the Graph object are modified, I want all other consumers of that object to be notified. In languages like C# I would have a setter in which I would raise an event. What is a proper way to create events in custom JavaScript objects?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
user1044169
  • 2,686
  • 6
  • 35
  • 64

3 Answers3

3

Using JQuery, you can create and also attach events of any type to whatever object you want, at any time.

function Graph (dataType, provider){
   this.dataType = dataType;
   this.provider = provider;
}

var g = new Graph;

g.dataType = "whatever1";
g.provider = "whatever2";
g.event = $.Event("mywhateverEvent");
g.myOwnProperty2 = $.Event("thisisAnEventToo");

Now you can manipulate your event further, doing whatever you want to that event, using something like:

g.event = <whateverCodeIWant>;
g.myOwnProperty2 = <whateverCodeIwant2>

Since you seem to like constructors, you can also do it like this:

function Graph (dataType, provider, evt){
   this.dataType = dataType;
   this.provider = provider;
   this.evt = evt
}

var myevt =  $.Event("whateverEvent");
myevt = <codeTomanipulatemyEventFurtherNowIfIWantTo>;
var g = new Graph("datawhatever", "providerwhatever", myevt);
$("whateverIWant").bind(myevt); 
//or whatever other binding - it will bind to that very event
$("whateverIWant").bind(g.evt);//equivalent to above line- binds to same event object
sajawikio
  • 1,516
  • 7
  • 12
  • What if multiple pieces of code want to subscribe to the same event on the same object. How would that be handled? Thanks. – user1044169 Sep 04 '12 at 04:44
  • See my reworked example. The Event object may be bound to, manipulated, etc. at any time, by any other object. – sajawikio Sep 04 '12 at 04:54
1

Object.defineProperty is what you want (assuming you are all right with not supporting IE < 9 or Firefox < 4 on the desktop)

function Graph (dataType, provider){
   this._dataType = dataType;
   this._provider = provider;
}

Graph.prototype = {
    get dataType() {
        return this._dataType;
    },
    set dataType(data) {
        yourEventDispatcher.trigger("datatype modified");
        this._dataType = data;
    },
    get provider() {
        return this._provider;
    },
    set provider(data) {
        yourEventDispatcher.trigger("provider modified");
        this._provider = data;
    }
};

See also: Javascript getters and setters for dummies?

Community
  • 1
  • 1
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
  • I like this. Very nice. Just curious - what if I had like 50 properties - any way I could trigger that for *any* property change, or I have to define 50 setters? – sajawikio Sep 04 '12 at 04:46
  • @sajawikio - currently you would need to define 50 setters - there is a proposal in the works for [an API to monitor all the properties of an object (Proxy)](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Proxy) but it is in the draft phase at the moment. – Sean Vieira Sep 04 '12 at 05:05
  • Thanks. But IE < 9 is a problem in this case. – user1044169 Sep 04 '12 at 10:27
0

Use an EventEmitter library, such as https://github.com/Wolfy87/EventEmitter. The full guide is here, but in a nutshell you'd load the EventEmitter javascript file and then do something like this:

Graph.prototype = Object.clone(EventEmitter.prototype);

and after that you can do

var g = new Graph("Blah", "Blah");
g.emitEvent('foo');
Femi
  • 64,273
  • 8
  • 118
  • 148
  • Just bear in mind that `Object.clone` is a new method that isn't particularly cross browser. You can write your own cloning method or use a library pretty easily though. There are some [great questions about cloning](http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-a-javascript-object) too. – Olical Oct 26 '12 at 08:27