Everything comes out of the Noweb file now.
This commit is contained in:
parent
40df6a023f
commit
b7603b24f8
67
Makefile
67
Makefile
|
@ -1,13 +1,31 @@
|
|||
.SUFFIXES: .nw .js .pdf .html .tex
|
||||
.SUFFIXES: .nw .js .pdf .html .tex .haml .css .stylus
|
||||
|
||||
NOTANGLE= notangle
|
||||
NOWEAVE= noweave
|
||||
ECHO= /bin/echo
|
||||
STYLUS= stylus
|
||||
HAML= haml
|
||||
COFFEE= coffee
|
||||
|
||||
all: index.html store.js
|
||||
all: index.html store.js jsonstore.css
|
||||
|
||||
.nw.html:
|
||||
$(NOWEAVE) -filter l2h -delay -x -index -autodefs c -html $*.nw > $*.html
|
||||
index.html: index.haml
|
||||
$(HAML) --unix-newlines --no-escape-attrs --double-quote-attribute $*.haml > $*.html
|
||||
|
||||
index.haml: backbonestore.nw
|
||||
$(NOTANGLE) -c -R$@ $< > $*.haml
|
||||
|
||||
jsonstore.css: jsonstore.styl
|
||||
$(STYLUS) $*.styl
|
||||
|
||||
jsonstore.styl: backbonestore.nw
|
||||
$(NOTANGLE) -c -R$@ $< > $@
|
||||
|
||||
store.js: store.coffee
|
||||
$(COFFEE) --compile $<
|
||||
|
||||
store.coffee: backbonestore.nw
|
||||
$(NOTANGLE) -c -R$@ $< > $@
|
||||
|
||||
.nw.tex:
|
||||
$(NOWEAVE) -x -delay $*.nw > $*.tex #$
|
||||
|
@ -19,47 +37,6 @@ all: index.html store.js
|
|||
xelatex *$.tex; \
|
||||
done
|
||||
|
||||
.nw.js:
|
||||
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
|
||||
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-js-tmp
|
||||
@ if [ -s "$*.nw-js-tmp" ]; then \
|
||||
mv $*.nw-js-tmp $@; \
|
||||
else \
|
||||
echo "$@ not found in $<"; \
|
||||
rm $*.nw-js-tmp; \
|
||||
fi
|
||||
|
||||
jsonstore.styl: backbonestore.nw
|
||||
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
|
||||
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-styl-tmp
|
||||
@ if [ -s "$*.nw-styl-tmp" ]; then \
|
||||
mv $*.nw-styl-tmp $@; \
|
||||
else \
|
||||
echo "$@ not found in $<"; \
|
||||
rm $*.nw-styl-tmp; \
|
||||
fi
|
||||
|
||||
store.js: backbonestore.nw
|
||||
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
|
||||
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
|
||||
@ if [ -s "$*.nw-html-tmp" ]; then \
|
||||
mv $*.nw-html-tmp $@; \
|
||||
else \
|
||||
echo "$@ not found in $<"; \
|
||||
rm $*.nw-tmp; \
|
||||
fi
|
||||
|
||||
index.html:
|
||||
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
|
||||
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
|
||||
@ if [ -s "$*.nw-html-tmp" ]; then \
|
||||
mv $*.nw-html-tmp $@; \
|
||||
else \
|
||||
echo "$@ not found in $<"; \
|
||||
rm $*.nw-tmp; \
|
||||
fi
|
||||
|
||||
|
||||
clean:
|
||||
- rm -f *.tex *.dvi *.aux *.toc *.log *.out *.html *.js
|
||||
|
||||
|
|
|
@ -319,7 +319,7 @@ Before we move on, let's take a look at the HAML we're going to use
|
|||
for our one-page application. The code below compiles beautifully
|
||||
into the same HTML seen in the original Backbone Store.
|
||||
|
||||
<<index.html>>=
|
||||
<<index.haml>>=
|
||||
!!! 5
|
||||
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
|
||||
%head
|
||||
|
@ -688,7 +688,7 @@ $(document).ready () ->
|
|||
Here's the entirety of the program. Coffeescript provides its own
|
||||
namespace wrapper:
|
||||
|
||||
<<store.js>>=
|
||||
<<store.coffee>>=
|
||||
<<product models>>
|
||||
|
||||
<<cart models>>
|
||||
|
@ -779,11 +779,16 @@ body
|
|||
img
|
||||
border: 0
|
||||
|
||||
#productlistview
|
||||
ul
|
||||
list-style: none
|
||||
|
||||
.item
|
||||
float:left
|
||||
width: 250px
|
||||
margin-right: 3px
|
||||
padding: 2px
|
||||
margin-right: 10px
|
||||
margin-bottom: 10px
|
||||
padding: 5px
|
||||
rounded(5px)
|
||||
border: 1px solid #ccc
|
||||
text-align:center
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
%head
|
||||
%title The Backbone Store
|
||||
%link{:charset => "utf-8", :href => "jsonstore.css", :rel => "stylesheet", :type => "text/css"}/
|
||||
|
||||
%script#store_index_template(type="text/x-underscore-tmplate")
|
||||
%h1 Product Catalog
|
||||
%ul
|
||||
|
@ -12,9 +11,9 @@
|
|||
.item-image
|
||||
%a{:href => "#item/<%= p.id %>"}
|
||||
%img{:src => "<%= p.image %>", :alt => "<%= p.title %>"}/
|
||||
.item-artist <%= p.artist %>
|
||||
.item-title <%= p.title %>
|
||||
.item-price $<%= p.price %>
|
||||
.item-artist <%= p.artist %>
|
||||
.item-title <%= p.title %>
|
||||
.item-price $<%= p.price %>
|
||||
<% } %>
|
||||
|
||||
%script#store_item_template(type= "text/x-underscore-template")
|
||||
|
@ -37,10 +36,10 @@
|
|||
%a(href="<%= url %>") Buy this item on Amazon
|
||||
.back-link
|
||||
%a(href="#") « Back to Items
|
||||
|
||||
%script#store_cart_template(type="text/x-underscore-template")
|
||||
%p Items: <%= count %> ($<%= cost %>)
|
||||
|
||||
</head>
|
||||
%body
|
||||
#container
|
||||
#header
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
<img alt="<%= p.title %>" src="<%= p.image %>" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item-artist"><%= p.artist %></div>
|
||||
<div class="item-title"><%= p.title %></div>
|
||||
<div class="item-price">$<%= p.price %></div>
|
||||
</li>
|
||||
<div class="item-artist"><%= p.artist %></div>
|
||||
<div class="item-title"><%= p.title %></div>
|
||||
<div class="item-price">$<%= p.price %></div>
|
||||
<% } %>
|
||||
</ul>
|
||||
</script>
|
||||
|
@ -49,6 +49,7 @@
|
|||
<script id="store_cart_template" type="text/x-underscore-template">
|
||||
<p>Items: <%= count %> ($<%= cost %>)</p>
|
||||
</script>
|
||||
</head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
|
|
|
@ -29,11 +29,15 @@ body {
|
|||
img {
|
||||
border: 0;
|
||||
}
|
||||
#productlistview ul {
|
||||
list-style: none;
|
||||
}
|
||||
.item {
|
||||
float: left;
|
||||
width: 250px;
|
||||
margin-right: 3px;
|
||||
padding: 2px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 5px;
|
||||
-moz-border-radius-topleft: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
-moz-border-radius-bottomleft: 5px;
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
rounded(radius)
|
||||
-moz-border-radius-topleft: radius
|
||||
-moz-border-radius-topright: radius
|
||||
-moz-border-radius-bottomleft: radius
|
||||
-moz-border-radius-bottomright: radius
|
||||
-webkit-border-bottom-right-radius: radius
|
||||
-webkit-border-top-left-radius: radius
|
||||
-webkit-border-top-right-radius: radius
|
||||
-webkit-border-bottom-left-radius: radius
|
||||
border-bottom-right-radius: radius
|
||||
border-top-left-radius: radius
|
||||
border-top-right-radius: radius
|
||||
border-bottom-left-radius: radius
|
||||
|
||||
body
|
||||
font-family: "Lucida Grande", Lucida, Helvetica, Arial, sans-serif
|
||||
background: #FFF
|
||||
color: #333
|
||||
margin: 0px
|
||||
padding: 0px
|
||||
|
||||
|
||||
#header
|
||||
background: #C97E41
|
||||
margin: 0px
|
||||
padding: 20px
|
||||
|
||||
h1
|
||||
font-family: Inconsolata, Monaco, Courier, mono
|
||||
color: #FFF
|
||||
margin: 0px
|
||||
|
||||
.cart-info
|
||||
position: absolute
|
||||
top: 0px
|
||||
right: 0px
|
||||
text-align: right
|
||||
padding: 10px
|
||||
background: #714625
|
||||
color: #FFF
|
||||
font-size: 12px
|
||||
font-weight: bold
|
||||
|
||||
img
|
||||
border: 0
|
||||
|
||||
#productlistview
|
||||
ul
|
||||
list-style: none
|
||||
|
||||
.item
|
||||
float:left
|
||||
width: 250px
|
||||
margin-right: 10px
|
||||
margin-bottom: 10px
|
||||
padding: 5px
|
||||
rounded(5px)
|
||||
border: 1px solid #ccc
|
||||
text-align:center
|
||||
font-size: 12px
|
||||
|
||||
.item-title
|
||||
font-weight: bold
|
||||
|
||||
.item-artist
|
||||
font-weight: bold
|
||||
font-size: 14px
|
||||
|
||||
.item-detail
|
||||
|
||||
.item-image
|
||||
float:left
|
||||
|
||||
.item-info
|
||||
padding: 100px 10px 0px 10px
|
||||
|
26
store.coffee
26
store.coffee
|
@ -10,10 +10,13 @@ class ProductCollection extends Backbone.Collection
|
|||
comparator: (item) ->
|
||||
item.get('title')
|
||||
|
||||
|
||||
class Item extends Backbone.Model
|
||||
update: (amount) ->
|
||||
@set {quantity: @get('quantity') + amount}
|
||||
@set
|
||||
quantity: @get('quantity')
|
||||
|
||||
price: () ->
|
||||
@get('product').get('price') * @get('quantity')
|
||||
|
||||
class ItemCollection extends Backbone.Collection
|
||||
model: Item
|
||||
|
@ -34,10 +37,9 @@ class ItemCollection extends Backbone.Collection
|
|||
@reduce addup, 0
|
||||
|
||||
getTotalCost: () ->
|
||||
addup = (memo, obj) ->
|
||||
(obj.get('product').get('price') *
|
||||
obj.get('quantity')) + memo
|
||||
@reduce addup, 0
|
||||
addup = (memo, obj) ->obj.price() + memo
|
||||
@reduce(addup, 0);
|
||||
|
||||
|
||||
class _BaseView extends Backbone.View
|
||||
parent: $('#main')
|
||||
|
@ -52,11 +54,7 @@ class _BaseView extends Backbone.View
|
|||
hide: () ->
|
||||
if not @el.is(':visible')
|
||||
return null
|
||||
|
||||
# Make a note here about how the => operator replaces the need for
|
||||
# _.bind()
|
||||
promise = $.Deferred (dfd) => @el.fadeOut('fast', dfd.resolve)
|
||||
@trigger 'hide', @
|
||||
promise.promise()
|
||||
|
||||
show: () ->
|
||||
|
@ -64,7 +62,6 @@ class _BaseView extends Backbone.View
|
|||
return
|
||||
|
||||
promise = $.Deferred (dfd) => @el.fadeIn('fast', dfd.resolve)
|
||||
@trigger 'show', @
|
||||
promise.promise()
|
||||
|
||||
|
||||
|
@ -80,6 +77,7 @@ class ProductListView extends _BaseView
|
|||
@el.html(_.template(@template, {'products': @collection.toJSON()}))
|
||||
@
|
||||
|
||||
|
||||
class ProductView extends _BaseView
|
||||
id: 'productitemview'
|
||||
template: $("#store_item_template").html()
|
||||
|
@ -95,7 +93,7 @@ class ProductView extends _BaseView
|
|||
|
||||
update: (e) ->
|
||||
e.preventDefault()
|
||||
@item.update parseInt($('.uqf').val())
|
||||
@item.update parseInt(@$('.uqf').val())
|
||||
|
||||
updateOnEnter: (e) ->
|
||||
if (e.keyCode == 13)
|
||||
|
@ -105,6 +103,7 @@ class ProductView extends _BaseView
|
|||
@el.html(_.template(@template, @model.toJSON()));
|
||||
@
|
||||
|
||||
|
||||
class CartWidget extends Backbone.View
|
||||
el: $('.cart-info')
|
||||
template: $('#store_cart_template').html()
|
||||
|
@ -119,6 +118,7 @@ class CartWidget extends Backbone.View
|
|||
tel.animate({paddingTop: '30px'}).animate({paddingTop: '10px'})
|
||||
@
|
||||
|
||||
|
||||
class BackboneStore extends Backbone.Router
|
||||
views: {}
|
||||
products: null
|
||||
|
@ -146,6 +146,7 @@ class BackboneStore extends Backbone.Router
|
|||
_.select(_.map(@views, (v) -> return v.hide()),
|
||||
(t) -> t != null)
|
||||
|
||||
|
||||
index: () ->
|
||||
view = @views['_index']
|
||||
$.when(@hideAllViews()).then(() -> view.show())
|
||||
|
@ -159,6 +160,7 @@ class BackboneStore extends Backbone.Router
|
|||
$.when(@hideAllViews()).then(
|
||||
() -> view.show())
|
||||
|
||||
|
||||
$(document).ready () ->
|
||||
new BackboneStore();
|
||||
Backbone.history.start();
|
||||
|
|
463
store.js
463
store.js
|
@ -1,203 +1,264 @@
|
|||
(function() {
|
||||
|
||||
var Product = Backbone.Model.extend({})
|
||||
|
||||
var ProductCollection = Backbone.Collection.extend({
|
||||
model: Product,
|
||||
|
||||
initialize: function(models, options) {
|
||||
this.url = options.url;
|
||||
},
|
||||
|
||||
comparator: function(item) {
|
||||
return item.get('title');
|
||||
}
|
||||
});
|
||||
|
||||
var Item = Backbone.Model.extend({
|
||||
update: function(amount) {
|
||||
this.set({'quantity': this.get('quantity') + amount});
|
||||
}
|
||||
});
|
||||
|
||||
var ItemCollection = Backbone.Collection.extend({
|
||||
model: Item,
|
||||
getOrCreateItemForProduct: function(product) {
|
||||
var i,
|
||||
pid = product.get('id'),
|
||||
o = this.detect(function(obj) {
|
||||
return (obj.get('product').get('id') == pid);
|
||||
});
|
||||
if (o) {
|
||||
return o;
|
||||
}
|
||||
i = new Item({'product': product, 'quantity': 0})
|
||||
this.add(i, {silent: true})
|
||||
return i;
|
||||
},
|
||||
getTotalCount: function() {
|
||||
return this.reduce(function(memo, obj) {
|
||||
return obj.get('quantity') + memo; }, 0);
|
||||
},
|
||||
getTotalCost: function() {
|
||||
return this.reduce(function(memo, obj) {
|
||||
return (obj.get('product').get('price') *
|
||||
obj.get('quantity')) + memo; }, 0);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
var _BaseView = Backbone.View.extend({
|
||||
parent: $('#main'),
|
||||
className: 'viewport',
|
||||
|
||||
initialize: function() {
|
||||
this.el = $(this.el);
|
||||
this.el.hide();
|
||||
this.parent.append(this.el);
|
||||
return this;
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
if (this.el.is(":visible") === false) {
|
||||
return null;
|
||||
}
|
||||
promise = $.Deferred(_.bind(function(dfd) {
|
||||
this.el.fadeOut('fast', dfd.resolve)}, this)).promise();
|
||||
this.trigger('hide', this);
|
||||
return promise;
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if (this.el.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
promise = $.Deferred(_.bind(function(dfd) {
|
||||
this.el.fadeIn('fast', dfd.resolve) }, this)).promise();
|
||||
|
||||
this.trigger('show', this);
|
||||
return promise;
|
||||
}
|
||||
});
|
||||
|
||||
var ProductListView = _BaseView.extend({
|
||||
id: 'productlistview',
|
||||
template: $("#store_index_template").html(),
|
||||
|
||||
initialize: function(options) {
|
||||
this.constructor.__super__.initialize.apply(this, [options])
|
||||
this.collection.bind('reset', _.bind(this.render, this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.el.html(_.template(this.template,
|
||||
{'products': this.collection.toJSON()}))
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var ProductView = _BaseView.extend({
|
||||
id: 'productitemview',
|
||||
template: $("#store_item_template").html(),
|
||||
initialize: function(options) {
|
||||
this.constructor.__super__.initialize.apply(this, [options])
|
||||
this.itemcollection = options.itemcollection;
|
||||
this.item = this.itemcollection.getOrCreateItemForProduct(this.model);
|
||||
return this;
|
||||
},
|
||||
|
||||
events: {
|
||||
"keypress .uqf" : "updateOnEnter",
|
||||
"click .uq" : "update",
|
||||
},
|
||||
|
||||
update: function(e) {
|
||||
e.preventDefault();
|
||||
this.item.update(parseInt($('.uqf').val()));
|
||||
},
|
||||
|
||||
updateOnEnter: function(e) {
|
||||
if (e.keyCode == 13) {
|
||||
return this.update(e);
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.el.html(_.template(this.template, this.model.toJSON()));
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
var CartWidget = Backbone.View.extend({
|
||||
el: $('.cart-info'),
|
||||
template: $('#store_cart_template').html(),
|
||||
|
||||
initialize: function() {
|
||||
this.collection.bind('change', _.bind(this.render, this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
console.log(arguments);
|
||||
this.el.html(
|
||||
_.template(this.template, {
|
||||
'count': this.collection.getTotalCount(),
|
||||
'cost': this.collection.getTotalCost()
|
||||
})).animate({paddingTop: '30px'})
|
||||
.animate({paddingTop: '10px'});
|
||||
}
|
||||
});
|
||||
|
||||
var BackboneStore = Backbone.Router.extend({
|
||||
views: {},
|
||||
products: null,
|
||||
cart: null,
|
||||
|
||||
routes: {
|
||||
"": "index",
|
||||
"item/:id": "product",
|
||||
},
|
||||
|
||||
initialize: function(data) {
|
||||
this.cart = new ItemCollection();
|
||||
new CartWidget({collection: this.cart});
|
||||
|
||||
this.products = new ProductCollection([], {
|
||||
url: 'data/items.json'});
|
||||
this.views = {
|
||||
'_index': new ProductListView({
|
||||
collection: this.products
|
||||
})
|
||||
};
|
||||
$.when(this.products.fetch({reset: true}))
|
||||
.then(function() { window.location.hash = ''; });
|
||||
return this;
|
||||
},
|
||||
|
||||
hideAllViews: function () {
|
||||
return _.select(
|
||||
_.map(this.views, function(v) { return v.hide(); }),
|
||||
function (t) { return t != null });
|
||||
},
|
||||
|
||||
index: function() {
|
||||
var view = this.views['_index'];
|
||||
$.when(this.hideAllViews()).then(
|
||||
function() { return view.show(); });
|
||||
},
|
||||
|
||||
product: function(id) {
|
||||
var product, v, view;
|
||||
product = this.products.detect(function(p) { return p.get('id') == (id); })
|
||||
view = ((v = this.views)['item.' + id]) || (v['item.' + id] = (
|
||||
new ProductView({model: product,
|
||||
itemcollection: this.cart}).render()));
|
||||
$.when(this.hideAllViews()).then(
|
||||
function() { view.show(); });
|
||||
}
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
new BackboneStore();
|
||||
Backbone.history.start();
|
||||
});
|
||||
var BackboneStore, CartWidget, Item, ItemCollection, Product, ProductCollection, ProductListView, ProductView, _BaseView;
|
||||
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
|
||||
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
|
||||
function ctor() { this.constructor = child; }
|
||||
ctor.prototype = parent.prototype;
|
||||
child.prototype = new ctor;
|
||||
child.__super__ = parent.prototype;
|
||||
return child;
|
||||
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||
Product = (function() {
|
||||
__extends(Product, Backbone.Model);
|
||||
function Product() {
|
||||
Product.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
return Product;
|
||||
})();
|
||||
ProductCollection = (function() {
|
||||
__extends(ProductCollection, Backbone.Collection);
|
||||
function ProductCollection() {
|
||||
ProductCollection.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
ProductCollection.prototype.model = Product;
|
||||
ProductCollection.prototype.initialize = function(models, options) {
|
||||
this.url = options.url;
|
||||
return this;
|
||||
};
|
||||
ProductCollection.prototype.comparator = function(item) {
|
||||
return item.get('title');
|
||||
};
|
||||
return ProductCollection;
|
||||
})();
|
||||
Item = (function() {
|
||||
__extends(Item, Backbone.Model);
|
||||
function Item() {
|
||||
Item.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
Item.prototype.update = function(amount) {
|
||||
return this.set({
|
||||
quantity: this.get('quantity')
|
||||
});
|
||||
};
|
||||
Item.prototype.price = function() {
|
||||
return this.get('product').get('price') * this.get('quantity');
|
||||
};
|
||||
return Item;
|
||||
})();
|
||||
ItemCollection = (function() {
|
||||
__extends(ItemCollection, Backbone.Collection);
|
||||
function ItemCollection() {
|
||||
ItemCollection.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
ItemCollection.prototype.model = Item;
|
||||
ItemCollection.prototype.getOrCreateItemForProduct = function(product) {
|
||||
var i, pid;
|
||||
pid = product.get('id');
|
||||
i = this.detect(function(obj) {
|
||||
return obj.get('product').get('id') === pid;
|
||||
});
|
||||
if (i) {
|
||||
return i;
|
||||
}
|
||||
i = new Item({
|
||||
product: product,
|
||||
quantity: 0
|
||||
});
|
||||
this.add(i, {
|
||||
silent: true
|
||||
});
|
||||
return i;
|
||||
};
|
||||
ItemCollection.prototype.getTotalCount = function() {
|
||||
var addup;
|
||||
addup = function(memo, obj) {
|
||||
return obj.get('quantity') + memo;
|
||||
};
|
||||
return this.reduce(addup, 0);
|
||||
};
|
||||
ItemCollection.prototype.getTotalCost = function() {
|
||||
var addup;
|
||||
addup = function(memo, obj) {
|
||||
return obj.price() + memo;
|
||||
};
|
||||
return this.reduce(addup, 0);
|
||||
};
|
||||
return ItemCollection;
|
||||
})();
|
||||
_BaseView = (function() {
|
||||
__extends(_BaseView, Backbone.View);
|
||||
function _BaseView() {
|
||||
_BaseView.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
_BaseView.prototype.parent = $('#main');
|
||||
_BaseView.prototype.className = 'viewport';
|
||||
_BaseView.prototype.initialize = function() {
|
||||
this.el = $(this.el);
|
||||
this.el.hide();
|
||||
this.parent.append(this.el);
|
||||
return this;
|
||||
};
|
||||
_BaseView.prototype.hide = function() {
|
||||
var promise;
|
||||
if (!this.el.is(':visible')) {
|
||||
return null;
|
||||
}
|
||||
promise = $.Deferred(__bind(function(dfd) {
|
||||
return this.el.fadeOut('fast', dfd.resolve);
|
||||
}, this));
|
||||
return promise.promise();
|
||||
};
|
||||
_BaseView.prototype.show = function() {
|
||||
var promise;
|
||||
if (this.el.is(':visible')) {
|
||||
return;
|
||||
}
|
||||
promise = $.Deferred(__bind(function(dfd) {
|
||||
return this.el.fadeIn('fast', dfd.resolve);
|
||||
}, this));
|
||||
return promise.promise();
|
||||
};
|
||||
return _BaseView;
|
||||
})();
|
||||
ProductListView = (function() {
|
||||
__extends(ProductListView, _BaseView);
|
||||
function ProductListView() {
|
||||
ProductListView.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
ProductListView.prototype.id = 'productlistview';
|
||||
ProductListView.prototype.template = $("#store_index_template").html();
|
||||
ProductListView.prototype.initialize = function(options) {
|
||||
this.constructor.__super__.initialize.apply(this, [options]);
|
||||
return this.collection.bind('reset', _.bind(this.render, this));
|
||||
};
|
||||
ProductListView.prototype.render = function() {
|
||||
this.el.html(_.template(this.template, {
|
||||
'products': this.collection.toJSON()
|
||||
}));
|
||||
return this;
|
||||
};
|
||||
return ProductListView;
|
||||
})();
|
||||
ProductView = (function() {
|
||||
__extends(ProductView, _BaseView);
|
||||
function ProductView() {
|
||||
ProductView.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
ProductView.prototype.id = 'productitemview';
|
||||
ProductView.prototype.template = $("#store_item_template").html();
|
||||
ProductView.prototype.initialize = function(options) {
|
||||
this.constructor.__super__.initialize.apply(this, [options]);
|
||||
this.itemcollection = options.itemcollection;
|
||||
this.item = this.itemcollection.getOrCreateItemForProduct(this.model);
|
||||
return this;
|
||||
};
|
||||
ProductView.prototype.events = {
|
||||
"keypress .uqf": "updateOnEnter",
|
||||
"click .uq": "update"
|
||||
};
|
||||
ProductView.prototype.update = function(e) {
|
||||
e.preventDefault();
|
||||
return this.item.update(parseInt(this.$('.uqf').val()));
|
||||
};
|
||||
ProductView.prototype.updateOnEnter = function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
return this.update(e);
|
||||
}
|
||||
};
|
||||
ProductView.prototype.render = function() {
|
||||
this.el.html(_.template(this.template, this.model.toJSON()));
|
||||
return this;
|
||||
};
|
||||
return ProductView;
|
||||
})();
|
||||
CartWidget = (function() {
|
||||
__extends(CartWidget, Backbone.View);
|
||||
function CartWidget() {
|
||||
CartWidget.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
CartWidget.prototype.el = $('.cart-info');
|
||||
CartWidget.prototype.template = $('#store_cart_template').html();
|
||||
CartWidget.prototype.initialize = function() {
|
||||
return this.collection.bind('change', _.bind(this.render, this));
|
||||
};
|
||||
CartWidget.prototype.render = function() {
|
||||
var tel;
|
||||
tel = this.el.html(_.template(this.template, {
|
||||
'count': this.collection.getTotalCount(),
|
||||
'cost': this.collection.getTotalCost()
|
||||
}));
|
||||
tel.animate({
|
||||
paddingTop: '30px'
|
||||
}).animate({
|
||||
paddingTop: '10px'
|
||||
});
|
||||
return this;
|
||||
};
|
||||
return CartWidget;
|
||||
})();
|
||||
BackboneStore = (function() {
|
||||
__extends(BackboneStore, Backbone.Router);
|
||||
function BackboneStore() {
|
||||
BackboneStore.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
BackboneStore.prototype.views = {};
|
||||
BackboneStore.prototype.products = null;
|
||||
BackboneStore.prototype.cart = null;
|
||||
BackboneStore.prototype.routes = {
|
||||
"": "index",
|
||||
"item/:id": "product"
|
||||
};
|
||||
BackboneStore.prototype.initialize = function(data) {
|
||||
this.cart = new ItemCollection();
|
||||
new CartWidget({
|
||||
collection: this.cart
|
||||
});
|
||||
this.products = new ProductCollection([], {
|
||||
url: 'data/items.json'
|
||||
});
|
||||
this.views = {
|
||||
'_index': new ProductListView({
|
||||
collection: this.products
|
||||
})
|
||||
};
|
||||
$.when(this.products.fetch({
|
||||
reset: true
|
||||
})).then(function() {
|
||||
return window.location.hash = '';
|
||||
});
|
||||
return this;
|
||||
};
|
||||
BackboneStore.prototype.hideAllViews = function() {
|
||||
return _.select(_.map(this.views, function(v) {
|
||||
return v.hide();
|
||||
}), function(t) {
|
||||
return t !== null;
|
||||
});
|
||||
};
|
||||
BackboneStore.prototype.index = function() {
|
||||
var view;
|
||||
view = this.views['_index'];
|
||||
return $.when(this.hideAllViews()).then(function() {
|
||||
return view.show();
|
||||
});
|
||||
};
|
||||
BackboneStore.prototype.product = function(id) {
|
||||
var product, view, _base, _name;
|
||||
product = this.products.detect(function(p) {
|
||||
return p.get('id') === id;
|
||||
});
|
||||
view = ((_base = this.views)[_name = 'item.' + id] || (_base[_name] = new ProductView({
|
||||
model: product,
|
||||
itemcollection: this.cart
|
||||
}).render()));
|
||||
return $.when(this.hideAllViews()).then(function() {
|
||||
return view.show();
|
||||
});
|
||||
};
|
||||
return BackboneStore;
|
||||
})();
|
||||
$(document).ready(function() {
|
||||
new BackboneStore();
|
||||
return Backbone.history.start();
|
||||
});
|
||||
}).call(this);
|
||||
|
|
Loading…
Reference in New Issue