3

I have built a dom object Engine that has private/public fields/methods that I have simplified below:

function Engine(args){
   this.display = args.display;

   this.getDisplay = function(){return this.display;}
   this.alertMsg = function(msg){
      console.log(this.display);
      alert(msg);
   }
}

What I would like to do is build a custom event that would be triggered after the alert(msg) such as $(this.display).trigger("afterAlert");

function Engine(args){
   this.display = args.display;

   this.getDisplay = function(){return this.display;}
   this.alertMsg = function(msg){
      console.log(this.display);
      alert(msg);
      // trigger custom event here
      $(this.display).trigger("afterAlert");
   }
}

Now, this event could be empty or not. How would one or more objects declared later register to the "afterAlert" event? In my case, additional javascript files are loaded by the main file dynamically and could contain a code ressembling :

function new_obj(){
    bind("afterAlert", function(){
       alert("alert was called");
    });
}

2 Answers 2

4

See my answer from this question...repeated for clarity

I will tackle the register, triggering and unbinding of custom events.

jQuery has all the tools you need to register, bind and unbind to custom events.

Below is an example of hooking up two divs to a custom event called customAjaxStart. I can then trigger this function and both handlers will get called.

Quick Demo Here - Have the firebug/ie8 console enabled.

e.g

$( function() {

  $('#div1').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  $('#div2').bind('customAjaxStart', function(){
    console.log('#div1 ajax start fired');
    $(this).fadeTo('slow', 0.3);
  });

  //fire the custom event
  $.event.trigger('customAjaxStart');

  //unbind div1 from custom event
  $('#div1').unbind('customAjaxStart');

  //again trigger custom event - div1 handler will not fire this time
 $.event.trigger('customAjaxStart'); 
});

Taking the above as an example I would trigger the customAjaxStart from the global ajaxStart. Any listeners would be triggered automatically whenever an xhr call is about to be made (ideal for disabling your widgets or showing a loading gif etc) e.g

$.ajaxStart( function(){

    $.event.trigger('customAjaxStart');

});
Sign up to request clarification or add additional context in comments.

2 Comments

I can't make it work... is it possible to bind after the trigger has been declared?
the trigger is to call the function....here is another demo when I have a second button that attaches a new subscriber element and triggers again. Watch the ff console pastebin.me/1d9a8ac9e8c8cd7de3cd5e71d8583c20
2

I think what you are looking for is the Observer pattern. At least that's how I would implement it. The following code snippet uses different names but it does essentially what you want (allows registering for events, and even triggering):

    Observable = {
  addObserver: function(observer) {
    if (!this.__observers) this.__observers = [];
    this.__observers.push(observer);
  },
  addGlobalObserver: function(observer) {
    if (!this.__global_observers) this.__global_observers = [];
    this.__global_observers.push(observer);
  },
  removeObserver: function(observer) {
    var newObservers = [];
    var co;
    while (co = this.__observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__observers = newObservers;
    newObservers = [];
    while (co = this.__global_observers.pop()) {
      if (co != observer) newObservers.push(co)
    }
    this.__global_observers = newObservers;
  },
  notify: function(event) {
    var allObservers = this.__global_observers.concat(this.__observers);
    for (var i=0; i < allObservers.length; i++) {
      var o = allObservers[i];
      if (o[event]) {
        var args = []
        for (var j=1; j < arguments.length; j++) {
          args.push(arguments[j])
        };
        o[event].apply(this, args);
      }
    };
  },
  __global_observers: [],
  __initializer: function() {
    this.__observers = [];
  }
};

If you include this code into your class, you can register for events using addObserver() (addGlobalObserver() for "class level" events). Inside the object you trigger an event using notify().

Code taken from Coltrane.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.