Skip to content

Instantly share code, notes, and snippets.

@saaji
Last active August 29, 2015 13:56
Show Gist options
  • Save saaji/9238595 to your computer and use it in GitHub Desktop.
Save saaji/9238595 to your computer and use it in GitHub Desktop.
Tiny IOC in JavaScript
(function($) {
var o = $({});
$.registerComponent = function(key, component) {
o[key] = component;
};
$.unregisterComponent = function(key) {
o[key] = undefined;
};
$.invoke = function() {
var args = Array.prototype.slice.call(arguments);
var key = args.shift();
var func = args.shift();
return o[key][func].apply(o[key], args);
};
}(jQuery));
@saaji
Copy link
Author

saaji commented Feb 26, 2014

This tiny lib allows to inverse control of JS app by registering services and calling their functions. Unlike bigger implementations it does not bother with Dependency Inversion, although services potentially may call other services.

Common use cases for this lib are shopping carts, summary and/or status widgets, or service objects that collect data over steps of some wizard.

Here is the example of a simple shopping cart. It can be accessed directly and via events (using Tiny PubSub):

Cart = {
  items: [],
  initialize: function(){
    self = this;
    $.subscribe('/cart/add', this.addByEvent);
  },
  add: function(item, price){ 
    this.items.push({item: item, price: price});
  },
  addByEvent: function(_, item, price){ 
    self.items.push({item: item, price: price});
  },
  list: function() {
    console.log('Shopping cart contents:');
    this.items.forEach(function(i){
      console.log(i.item + ": $" + i.price + "");
    });
  },
  total: function() {
    sum = 0;
    this.items.forEach(function(i){
      sum += i.price;
    });
    console.log('-------------------');
    console.log('Total: $' + sum);
  }
};


// Let's register our global shopping cart
$.registerComponent('/cart', Cart);

// Now we can access it's methods not knowing that the Cart 
// object is being accessed.
$.invoke('/cart', 'initialize');

// Let's add some stuff...

// First — directly.
$.invoke('/cart', 'add', 'Bubble gum', 0.5);

// Then - indirectly, emulating message invoked by other widget(s)
$.publish('/cart/add', ['Coca-cola', 0.99]);

// Now we can access cart contents and total from any place in our JS
$.invoke('/cart', 'list');
$.invoke('/cart', 'total');


// Console output:
//
// Shopping cart contents:
// Bubble gum: $0.5
// Coca-cola: $0.99
// -------------------
// Total: $1.49

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