Skip to content

Instantly share code, notes, and snippets.

@amcdnl
Last active December 10, 2015 19:09
Show Gist options
  • Save amcdnl/4479819 to your computer and use it in GitHub Desktop.
Save amcdnl/4479819 to your computer and use it in GitHub Desktop.

Global Method Invoking

Sometimes you need the ability to call a globalish method from somewhere deep in your code. You have a few different options:

  • Expose a global method
  • Trigger an event on the DOM and the parent listens for it
  • Pass a instance of whatever into the child and call it from where

While each of these ways will accomplish the goal, they aren't that clean.

Why aren't they 'clean'?

  • Exposing a global method requires that method be in every page. What if you wanted to reuse this component on a different page? This limits your re-use and makes testing hard since your going to have to mock this in addition to your objects your widget might require.
  • Trigger an event on the dom, is eh. Especially if your method you need to call isn't related to the view at all, what if its a business-logic related method?
  • Passing a instance is cumbersome. Nuf said.

Ideally this is where a pub-sub system would come in handy; but I think there is a better way. What if you triggered an event on a object instead? For example, the following will trigger an event on the XMPP model when the server is ready.

Models.Xmpp.trigger('ready');

in another place in the code that worries about ready, I do:

"{Models.Xmpp} ready":function{ ... }

I know your about to say how is this different from the above things? Well your Models are likelky going to be tied to the thing your accessing anyway. Its cleaner than DOM because its related directly to the object.

My implementation looks like:

var trigger = function(name, args){
	var event = new jQuery.Event(name, {
		target: this,
		currentTarget: this
	});
	$.event.trigger(event, args, this, true );
};

can.Model('core.Model', {
	/* Static */
	trigger:function(){
		trigger.apply(this, arguments);
	}
},{
	/* Proto */
	trigger:function(){
		trigger.apply(this,arguments);
  		}
});

I put trigger on both prototype and static so we can trigger it both and depedning on the implementation get the right object we need.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment