3
\$\begingroup\$

So I've got a jquery project where I'm using an external class that has callback style events. Meaning, it has an "onSave" property that takes one function. However, I need to more than one other component to hook into it.

What I've settled on for now, goes like this:

var saveCallbacks = $.Callbacks();
saveCallbacks.fire.callbacks = saveCallbacks;
globalDoodad.onSave = saveCallbacks.fire;

which allows me to do this in my other components:

globalDoodad.onSave.callbacks.add( myMethod );

Is there a better, or at least more standard, way to handle this? It seems to be working ok, just has a bit of a smell to it.

\$\endgroup\$
1
  • \$\begingroup\$ Is confusing how you add a reference of an object to itself. What is the external class you are using? I created a gist once of a JS class that facilitates the creation of jQuery plugins with a jQuery UI style interface, no longer use but you might find it useful gist.github.com/ptejada/2269151 \$\endgroup\$
    – Pablo
    Feb 26, 2014 at 4:16

1 Answer 1

1
\$\begingroup\$

I think what you need is a global pub-sub facility. Modules you have subscribe to certain events. These subscriptions (functions) get executed when that event is published, usually with data.

This allows different modules, from different parts of your program, to interact even without direct visibility with each other. The only dependency visible to your modules is the pub-sub module.

For instance this:

// ModuleA.js
PubSub.module('moduleA',function(tower){
  tower.subscribe('foo',function(data){
    // executes when somewhere else publishes a foo
    alert('foo executed in A with ' + data.join(' '));
  });
});

// ModuleB.js
PubSub.module('moduleB',function(tower){
  tower.subscribe('foo',function(data){
    // executes when somewhere else publishes a foo
    alert('foo executed in B with ' + data.join(' '));
  });
});

// ModuleC.js
PubSub.module('moduleC',function(tower){
  $(document).on('click',function(){
    // publish a foo event, passing 1 and 2, which arrives as "data" in each handler
    tower.publish('foo','1','2');
  });
});

jQuery has built-in event-handling capabilities, which also allow custom events. You can use this ability as your pub-sub facility.

var test = $(document);            // You can bind it to any object. document is handy.
test.on('sampleevent',function(){  // Add a handler
  alert('executed');
});

test.trigger('sampleevent');       // Execute

You can also implement your own, which doubles as a good programming practice. Here's my version of it, which I based on Node.js's EventEmitter.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.