var cartModule = (function(postal, $){ var cartId = 0, cartTemplate = "#cart-tmpl", cartItemTemplate = "#cart-item-tmpl", cartChildrenSelector = "#cart-list", wireUpCart = function(cart) { postal.subscribe("cart", "init", _.bind(cart.init,cart)); postal.subscribe("cart", "item.add", function(item) { var member = cart.id + "-" + item.id; if(cart.items[member]) { cart.items[member].qty++; cart.items[member].notifyOfChange(); } else { cart.items[member] = new CartItem(_.extend(item, { qty: 1, cartId: cart.id }), new CartItemProxy(cartChildrenSelector)); } }); }, CartPrototype = { init: function() { this.items = {}; this.proxy.render(this); } }, Cart = function(domProxy) { var self = this; self.items = {}; self.id = cartId; self.proxy = domProxy; wireUpCart(this); }, CartDomProxyPrototype = { render: function(model) { $(this.selector).html(_.template($(cartTemplate).html(), model)); } }, CartDomProxy = function(selector) { this.selector = selector; }, CartItemPrototype = { notifyOfChange: function() { this.proxy.render(this); } }, CartItem = function(item, domProxy) { this.cartId = item.cartId; this.description = item.description; this.price = item.price; this.productId = item.id; this.proxy = domProxy; this.qty = item.qty; this.notifyOfChange(); }, CartItemProxyPrototype = { render: function(model) { var item = $("#" + model.cartId + "-" + model.productId); if(item.length === 0) { $(this.selector).append(_.template($(cartItemTemplate).html(), model)); } else { item.replaceWith(_.template($(cartItemTemplate).html(), model)); } } }, CartItemProxy = function(selector) { this.selector = selector; }; Cart.prototype = CartPrototype; CartItem.prototype = CartItemPrototype; CartItemProxy.prototype = CartItemProxyPrototype; CartDomProxy.prototype = CartDomProxyPrototype; return { start: function(selector) { return new Cart(new CartDomProxy(selector)); } } })(postal, jQuery);