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
|
NOTANGLE= notangle
|
||||||
NOWEAVE= noweave
|
NOWEAVE= noweave
|
||||||
ECHO= /bin/echo
|
ECHO= /bin/echo
|
||||||
|
STYLUS= stylus
|
||||||
|
HAML= haml
|
||||||
|
COFFEE= coffee
|
||||||
|
|
||||||
all: index.html store.js
|
all: index.html store.js jsonstore.css
|
||||||
|
|
||||||
.nw.html:
|
index.html: index.haml
|
||||||
$(NOWEAVE) -filter l2h -delay -x -index -autodefs c -html $*.nw > $*.html
|
$(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:
|
.nw.tex:
|
||||||
$(NOWEAVE) -x -delay $*.nw > $*.tex #$
|
$(NOWEAVE) -x -delay $*.nw > $*.tex #$
|
||||||
|
@ -19,47 +37,6 @@ all: index.html store.js
|
||||||
xelatex *$.tex; \
|
xelatex *$.tex; \
|
||||||
done
|
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:
|
clean:
|
||||||
- rm -f *.tex *.dvi *.aux *.toc *.log *.out *.html *.js
|
- 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
|
for our one-page application. The code below compiles beautifully
|
||||||
into the same HTML seen in the original Backbone Store.
|
into the same HTML seen in the original Backbone Store.
|
||||||
|
|
||||||
<<index.html>>=
|
<<index.haml>>=
|
||||||
!!! 5
|
!!! 5
|
||||||
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
|
%html{:xmlns => "http://www.w3.org/1999/xhtml"}
|
||||||
%head
|
%head
|
||||||
|
@ -688,7 +688,7 @@ $(document).ready () ->
|
||||||
Here's the entirety of the program. Coffeescript provides its own
|
Here's the entirety of the program. Coffeescript provides its own
|
||||||
namespace wrapper:
|
namespace wrapper:
|
||||||
|
|
||||||
<<store.js>>=
|
<<store.coffee>>=
|
||||||
<<product models>>
|
<<product models>>
|
||||||
|
|
||||||
<<cart models>>
|
<<cart models>>
|
||||||
|
@ -779,11 +779,16 @@ body
|
||||||
img
|
img
|
||||||
border: 0
|
border: 0
|
||||||
|
|
||||||
|
#productlistview
|
||||||
|
ul
|
||||||
|
list-style: none
|
||||||
|
|
||||||
.item
|
.item
|
||||||
float:left
|
float:left
|
||||||
width: 250px
|
width: 250px
|
||||||
margin-right: 3px
|
margin-right: 10px
|
||||||
padding: 2px
|
margin-bottom: 10px
|
||||||
|
padding: 5px
|
||||||
rounded(5px)
|
rounded(5px)
|
||||||
border: 1px solid #ccc
|
border: 1px solid #ccc
|
||||||
text-align:center
|
text-align:center
|
||||||
|
|
17
index.haml
17
index.haml
|
@ -3,7 +3,6 @@
|
||||||
%head
|
%head
|
||||||
%title The Backbone Store
|
%title The Backbone Store
|
||||||
%link{:charset => "utf-8", :href => "jsonstore.css", :rel => "stylesheet", :type => "text/css"}/
|
%link{:charset => "utf-8", :href => "jsonstore.css", :rel => "stylesheet", :type => "text/css"}/
|
||||||
|
|
||||||
%script#store_index_template(type="text/x-underscore-tmplate")
|
%script#store_index_template(type="text/x-underscore-tmplate")
|
||||||
%h1 Product Catalog
|
%h1 Product Catalog
|
||||||
%ul
|
%ul
|
||||||
|
@ -12,20 +11,20 @@
|
||||||
.item-image
|
.item-image
|
||||||
%a{:href => "#item/<%= p.id %>"}
|
%a{:href => "#item/<%= p.id %>"}
|
||||||
%img{:src => "<%= p.image %>", :alt => "<%= p.title %>"}/
|
%img{:src => "<%= p.image %>", :alt => "<%= p.title %>"}/
|
||||||
.item-artist <%= p.artist %>
|
.item-artist <%= p.artist %>
|
||||||
.item-title <%= p.title %>
|
.item-title <%= p.title %>
|
||||||
.item-price $<%= p.price %>
|
.item-price $<%= p.price %>
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
%script#store_item_template(type= "text/x-underscore-template")
|
%script#store_item_template(type= "text/x-underscore-template")
|
||||||
.item-detail
|
.item-detail
|
||||||
.item-image
|
.item-image
|
||||||
%img(src="<%= large_image %>" alt="<%= title %>")/
|
%img(src="<%= large_image %>" alt="<%= title %>")/
|
||||||
.item-info
|
.item-info
|
||||||
.item-artist <%= artist %>
|
.item-artist <%= artist %>
|
||||||
.item-title <%= title %>
|
.item-title <%= title %>
|
||||||
.item-price $<%= price %>
|
.item-price $<%= price %>
|
||||||
.item-form
|
.item-form
|
||||||
%form(action="#/cart" method="post")
|
%form(action="#/cart" method="post")
|
||||||
%p
|
%p
|
||||||
%label Quantity:
|
%label Quantity:
|
||||||
|
@ -37,17 +36,17 @@
|
||||||
%a(href="<%= url %>") Buy this item on Amazon
|
%a(href="<%= url %>") Buy this item on Amazon
|
||||||
.back-link
|
.back-link
|
||||||
%a(href="#") « Back to Items
|
%a(href="#") « Back to Items
|
||||||
|
|
||||||
%script#store_cart_template(type="text/x-underscore-template")
|
%script#store_cart_template(type="text/x-underscore-template")
|
||||||
%p Items: <%= count %> ($<%= cost %>)
|
%p Items: <%= count %> ($<%= cost %>)
|
||||||
|
|
||||||
|
</head>
|
||||||
%body
|
%body
|
||||||
#container
|
#container
|
||||||
#header
|
#header
|
||||||
%h1
|
%h1
|
||||||
The Backbone Store
|
The Backbone Store
|
||||||
.cart-info
|
.cart-info
|
||||||
#main
|
#main
|
||||||
%script{:src => "jquery-1.6.2.min.js", :type => "text/javascript"}
|
%script{:src => "jquery-1.6.2.min.js", :type => "text/javascript"}
|
||||||
%script{:src => "underscore.js", :type => "text/javascript"}
|
%script{:src => "underscore.js", :type => "text/javascript"}
|
||||||
%script{:src => "backbone.js", :type => "text/javascript"}
|
%script{:src => "backbone.js", :type => "text/javascript"}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
<img alt="<%= p.title %>" src="<%= p.image %>" />
|
<img alt="<%= p.title %>" src="<%= p.image %>" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="item-artist"><%= p.artist %></div>
|
||||||
|
<div class="item-title"><%= p.title %></div>
|
||||||
|
<div class="item-price">$<%= p.price %></div>
|
||||||
</li>
|
</li>
|
||||||
<div class="item-artist"><%= p.artist %></div>
|
|
||||||
<div class="item-title"><%= p.title %></div>
|
|
||||||
<div class="item-price">$<%= p.price %></div>
|
|
||||||
<% } %>
|
<% } %>
|
||||||
</ul>
|
</ul>
|
||||||
</script>
|
</script>
|
||||||
|
@ -49,6 +49,7 @@
|
||||||
<script id="store_cart_template" type="text/x-underscore-template">
|
<script id="store_cart_template" type="text/x-underscore-template">
|
||||||
<p>Items: <%= count %> ($<%= cost %>)</p>
|
<p>Items: <%= count %> ($<%= cost %>)</p>
|
||||||
</script>
|
</script>
|
||||||
|
</head>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
|
|
|
@ -29,11 +29,15 @@ body {
|
||||||
img {
|
img {
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
#productlistview ul {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
.item {
|
.item {
|
||||||
float: left;
|
float: left;
|
||||||
width: 250px;
|
width: 250px;
|
||||||
margin-right: 3px;
|
margin-right: 10px;
|
||||||
padding: 2px;
|
margin-bottom: 10px;
|
||||||
|
padding: 5px;
|
||||||
-moz-border-radius-topleft: 5px;
|
-moz-border-radius-topleft: 5px;
|
||||||
-moz-border-radius-topright: 5px;
|
-moz-border-radius-topright: 5px;
|
||||||
-moz-border-radius-bottomleft: 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) ->
|
comparator: (item) ->
|
||||||
item.get('title')
|
item.get('title')
|
||||||
|
|
||||||
|
|
||||||
class Item extends Backbone.Model
|
class Item extends Backbone.Model
|
||||||
update: (amount) ->
|
update: (amount) ->
|
||||||
@set {quantity: @get('quantity') + amount}
|
@set
|
||||||
|
quantity: @get('quantity')
|
||||||
|
|
||||||
|
price: () ->
|
||||||
|
@get('product').get('price') * @get('quantity')
|
||||||
|
|
||||||
class ItemCollection extends Backbone.Collection
|
class ItemCollection extends Backbone.Collection
|
||||||
model: Item
|
model: Item
|
||||||
|
@ -34,10 +37,9 @@ class ItemCollection extends Backbone.Collection
|
||||||
@reduce addup, 0
|
@reduce addup, 0
|
||||||
|
|
||||||
getTotalCost: () ->
|
getTotalCost: () ->
|
||||||
addup = (memo, obj) ->
|
addup = (memo, obj) ->obj.price() + memo
|
||||||
(obj.get('product').get('price') *
|
@reduce(addup, 0);
|
||||||
obj.get('quantity')) + memo
|
|
||||||
@reduce addup, 0
|
|
||||||
|
|
||||||
class _BaseView extends Backbone.View
|
class _BaseView extends Backbone.View
|
||||||
parent: $('#main')
|
parent: $('#main')
|
||||||
|
@ -52,11 +54,7 @@ class _BaseView extends Backbone.View
|
||||||
hide: () ->
|
hide: () ->
|
||||||
if not @el.is(':visible')
|
if not @el.is(':visible')
|
||||||
return null
|
return null
|
||||||
|
|
||||||
# Make a note here about how the => operator replaces the need for
|
|
||||||
# _.bind()
|
|
||||||
promise = $.Deferred (dfd) => @el.fadeOut('fast', dfd.resolve)
|
promise = $.Deferred (dfd) => @el.fadeOut('fast', dfd.resolve)
|
||||||
@trigger 'hide', @
|
|
||||||
promise.promise()
|
promise.promise()
|
||||||
|
|
||||||
show: () ->
|
show: () ->
|
||||||
|
@ -64,7 +62,6 @@ class _BaseView extends Backbone.View
|
||||||
return
|
return
|
||||||
|
|
||||||
promise = $.Deferred (dfd) => @el.fadeIn('fast', dfd.resolve)
|
promise = $.Deferred (dfd) => @el.fadeIn('fast', dfd.resolve)
|
||||||
@trigger 'show', @
|
|
||||||
promise.promise()
|
promise.promise()
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,6 +77,7 @@ class ProductListView extends _BaseView
|
||||||
@el.html(_.template(@template, {'products': @collection.toJSON()}))
|
@el.html(_.template(@template, {'products': @collection.toJSON()}))
|
||||||
@
|
@
|
||||||
|
|
||||||
|
|
||||||
class ProductView extends _BaseView
|
class ProductView extends _BaseView
|
||||||
id: 'productitemview'
|
id: 'productitemview'
|
||||||
template: $("#store_item_template").html()
|
template: $("#store_item_template").html()
|
||||||
|
@ -95,7 +93,7 @@ class ProductView extends _BaseView
|
||||||
|
|
||||||
update: (e) ->
|
update: (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@item.update parseInt($('.uqf').val())
|
@item.update parseInt(@$('.uqf').val())
|
||||||
|
|
||||||
updateOnEnter: (e) ->
|
updateOnEnter: (e) ->
|
||||||
if (e.keyCode == 13)
|
if (e.keyCode == 13)
|
||||||
|
@ -105,6 +103,7 @@ class ProductView extends _BaseView
|
||||||
@el.html(_.template(@template, @model.toJSON()));
|
@el.html(_.template(@template, @model.toJSON()));
|
||||||
@
|
@
|
||||||
|
|
||||||
|
|
||||||
class CartWidget extends Backbone.View
|
class CartWidget extends Backbone.View
|
||||||
el: $('.cart-info')
|
el: $('.cart-info')
|
||||||
template: $('#store_cart_template').html()
|
template: $('#store_cart_template').html()
|
||||||
|
@ -119,6 +118,7 @@ class CartWidget extends Backbone.View
|
||||||
tel.animate({paddingTop: '30px'}).animate({paddingTop: '10px'})
|
tel.animate({paddingTop: '30px'}).animate({paddingTop: '10px'})
|
||||||
@
|
@
|
||||||
|
|
||||||
|
|
||||||
class BackboneStore extends Backbone.Router
|
class BackboneStore extends Backbone.Router
|
||||||
views: {}
|
views: {}
|
||||||
products: null
|
products: null
|
||||||
|
@ -146,6 +146,7 @@ class BackboneStore extends Backbone.Router
|
||||||
_.select(_.map(@views, (v) -> return v.hide()),
|
_.select(_.map(@views, (v) -> return v.hide()),
|
||||||
(t) -> t != null)
|
(t) -> t != null)
|
||||||
|
|
||||||
|
|
||||||
index: () ->
|
index: () ->
|
||||||
view = @views['_index']
|
view = @views['_index']
|
||||||
$.when(@hideAllViews()).then(() -> view.show())
|
$.when(@hideAllViews()).then(() -> view.show())
|
||||||
|
@ -159,6 +160,7 @@ class BackboneStore extends Backbone.Router
|
||||||
$.when(@hideAllViews()).then(
|
$.when(@hideAllViews()).then(
|
||||||
() -> view.show())
|
() -> view.show())
|
||||||
|
|
||||||
|
|
||||||
$(document).ready () ->
|
$(document).ready () ->
|
||||||
new BackboneStore();
|
new BackboneStore();
|
||||||
Backbone.history.start();
|
Backbone.history.start();
|
||||||
|
|
463
store.js
463
store.js
|
@ -1,203 +1,264 @@
|
||||||
(function() {
|
(function() {
|
||||||
|
var BackboneStore, CartWidget, Item, ItemCollection, Product, ProductCollection, ProductListView, ProductView, _BaseView;
|
||||||
var Product = Backbone.Model.extend({})
|
var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
|
||||||
|
for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
|
||||||
var ProductCollection = Backbone.Collection.extend({
|
function ctor() { this.constructor = child; }
|
||||||
model: Product,
|
ctor.prototype = parent.prototype;
|
||||||
|
child.prototype = new ctor;
|
||||||
initialize: function(models, options) {
|
child.__super__ = parent.prototype;
|
||||||
this.url = options.url;
|
return child;
|
||||||
},
|
}, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
|
||||||
|
Product = (function() {
|
||||||
comparator: function(item) {
|
__extends(Product, Backbone.Model);
|
||||||
return item.get('title');
|
function Product() {
|
||||||
}
|
Product.__super__.constructor.apply(this, arguments);
|
||||||
});
|
}
|
||||||
|
return Product;
|
||||||
var Item = Backbone.Model.extend({
|
})();
|
||||||
update: function(amount) {
|
ProductCollection = (function() {
|
||||||
this.set({'quantity': this.get('quantity') + amount});
|
__extends(ProductCollection, Backbone.Collection);
|
||||||
}
|
function ProductCollection() {
|
||||||
});
|
ProductCollection.__super__.constructor.apply(this, arguments);
|
||||||
|
}
|
||||||
var ItemCollection = Backbone.Collection.extend({
|
ProductCollection.prototype.model = Product;
|
||||||
model: Item,
|
ProductCollection.prototype.initialize = function(models, options) {
|
||||||
getOrCreateItemForProduct: function(product) {
|
this.url = options.url;
|
||||||
var i,
|
return this;
|
||||||
pid = product.get('id'),
|
};
|
||||||
o = this.detect(function(obj) {
|
ProductCollection.prototype.comparator = function(item) {
|
||||||
return (obj.get('product').get('id') == pid);
|
return item.get('title');
|
||||||
});
|
};
|
||||||
if (o) {
|
return ProductCollection;
|
||||||
return o;
|
})();
|
||||||
}
|
Item = (function() {
|
||||||
i = new Item({'product': product, 'quantity': 0})
|
__extends(Item, Backbone.Model);
|
||||||
this.add(i, {silent: true})
|
function Item() {
|
||||||
return i;
|
Item.__super__.constructor.apply(this, arguments);
|
||||||
},
|
}
|
||||||
getTotalCount: function() {
|
Item.prototype.update = function(amount) {
|
||||||
return this.reduce(function(memo, obj) {
|
return this.set({
|
||||||
return obj.get('quantity') + memo; }, 0);
|
quantity: this.get('quantity')
|
||||||
},
|
});
|
||||||
getTotalCost: function() {
|
};
|
||||||
return this.reduce(function(memo, obj) {
|
Item.prototype.price = function() {
|
||||||
return (obj.get('product').get('price') *
|
return this.get('product').get('price') * this.get('quantity');
|
||||||
obj.get('quantity')) + memo; }, 0);
|
};
|
||||||
|
return Item;
|
||||||
}
|
})();
|
||||||
});
|
ItemCollection = (function() {
|
||||||
|
__extends(ItemCollection, Backbone.Collection);
|
||||||
var _BaseView = Backbone.View.extend({
|
function ItemCollection() {
|
||||||
parent: $('#main'),
|
ItemCollection.__super__.constructor.apply(this, arguments);
|
||||||
className: 'viewport',
|
}
|
||||||
|
ItemCollection.prototype.model = Item;
|
||||||
initialize: function() {
|
ItemCollection.prototype.getOrCreateItemForProduct = function(product) {
|
||||||
this.el = $(this.el);
|
var i, pid;
|
||||||
this.el.hide();
|
pid = product.get('id');
|
||||||
this.parent.append(this.el);
|
i = this.detect(function(obj) {
|
||||||
return this;
|
return obj.get('product').get('id') === pid;
|
||||||
},
|
});
|
||||||
|
if (i) {
|
||||||
hide: function() {
|
return i;
|
||||||
if (this.el.is(":visible") === false) {
|
}
|
||||||
return null;
|
i = new Item({
|
||||||
}
|
product: product,
|
||||||
promise = $.Deferred(_.bind(function(dfd) {
|
quantity: 0
|
||||||
this.el.fadeOut('fast', dfd.resolve)}, this)).promise();
|
});
|
||||||
this.trigger('hide', this);
|
this.add(i, {
|
||||||
return promise;
|
silent: true
|
||||||
},
|
});
|
||||||
|
return i;
|
||||||
show: function() {
|
};
|
||||||
if (this.el.is(':visible')) {
|
ItemCollection.prototype.getTotalCount = function() {
|
||||||
return;
|
var addup;
|
||||||
}
|
addup = function(memo, obj) {
|
||||||
promise = $.Deferred(_.bind(function(dfd) {
|
return obj.get('quantity') + memo;
|
||||||
this.el.fadeIn('fast', dfd.resolve) }, this)).promise();
|
};
|
||||||
|
return this.reduce(addup, 0);
|
||||||
this.trigger('show', this);
|
};
|
||||||
return promise;
|
ItemCollection.prototype.getTotalCost = function() {
|
||||||
}
|
var addup;
|
||||||
});
|
addup = function(memo, obj) {
|
||||||
|
return obj.price() + memo;
|
||||||
var ProductListView = _BaseView.extend({
|
};
|
||||||
id: 'productlistview',
|
return this.reduce(addup, 0);
|
||||||
template: $("#store_index_template").html(),
|
};
|
||||||
|
return ItemCollection;
|
||||||
initialize: function(options) {
|
})();
|
||||||
this.constructor.__super__.initialize.apply(this, [options])
|
_BaseView = (function() {
|
||||||
this.collection.bind('reset', _.bind(this.render, this));
|
__extends(_BaseView, Backbone.View);
|
||||||
},
|
function _BaseView() {
|
||||||
|
_BaseView.__super__.constructor.apply(this, arguments);
|
||||||
render: function() {
|
}
|
||||||
this.el.html(_.template(this.template,
|
_BaseView.prototype.parent = $('#main');
|
||||||
{'products': this.collection.toJSON()}))
|
_BaseView.prototype.className = 'viewport';
|
||||||
return this;
|
_BaseView.prototype.initialize = function() {
|
||||||
}
|
this.el = $(this.el);
|
||||||
});
|
this.el.hide();
|
||||||
|
this.parent.append(this.el);
|
||||||
var ProductView = _BaseView.extend({
|
return this;
|
||||||
id: 'productitemview',
|
};
|
||||||
template: $("#store_item_template").html(),
|
_BaseView.prototype.hide = function() {
|
||||||
initialize: function(options) {
|
var promise;
|
||||||
this.constructor.__super__.initialize.apply(this, [options])
|
if (!this.el.is(':visible')) {
|
||||||
this.itemcollection = options.itemcollection;
|
return null;
|
||||||
this.item = this.itemcollection.getOrCreateItemForProduct(this.model);
|
}
|
||||||
return this;
|
promise = $.Deferred(__bind(function(dfd) {
|
||||||
},
|
return this.el.fadeOut('fast', dfd.resolve);
|
||||||
|
}, this));
|
||||||
events: {
|
return promise.promise();
|
||||||
"keypress .uqf" : "updateOnEnter",
|
};
|
||||||
"click .uq" : "update",
|
_BaseView.prototype.show = function() {
|
||||||
},
|
var promise;
|
||||||
|
if (this.el.is(':visible')) {
|
||||||
update: function(e) {
|
return;
|
||||||
e.preventDefault();
|
}
|
||||||
this.item.update(parseInt($('.uqf').val()));
|
promise = $.Deferred(__bind(function(dfd) {
|
||||||
},
|
return this.el.fadeIn('fast', dfd.resolve);
|
||||||
|
}, this));
|
||||||
updateOnEnter: function(e) {
|
return promise.promise();
|
||||||
if (e.keyCode == 13) {
|
};
|
||||||
return this.update(e);
|
return _BaseView;
|
||||||
}
|
})();
|
||||||
},
|
ProductListView = (function() {
|
||||||
|
__extends(ProductListView, _BaseView);
|
||||||
render: function() {
|
function ProductListView() {
|
||||||
this.el.html(_.template(this.template, this.model.toJSON()));
|
ProductListView.__super__.constructor.apply(this, arguments);
|
||||||
return this;
|
}
|
||||||
}
|
ProductListView.prototype.id = 'productlistview';
|
||||||
});
|
ProductListView.prototype.template = $("#store_index_template").html();
|
||||||
|
ProductListView.prototype.initialize = function(options) {
|
||||||
var CartWidget = Backbone.View.extend({
|
this.constructor.__super__.initialize.apply(this, [options]);
|
||||||
el: $('.cart-info'),
|
return this.collection.bind('reset', _.bind(this.render, this));
|
||||||
template: $('#store_cart_template').html(),
|
};
|
||||||
|
ProductListView.prototype.render = function() {
|
||||||
initialize: function() {
|
this.el.html(_.template(this.template, {
|
||||||
this.collection.bind('change', _.bind(this.render, this));
|
'products': this.collection.toJSON()
|
||||||
},
|
}));
|
||||||
|
return this;
|
||||||
render: function() {
|
};
|
||||||
console.log(arguments);
|
return ProductListView;
|
||||||
this.el.html(
|
})();
|
||||||
_.template(this.template, {
|
ProductView = (function() {
|
||||||
'count': this.collection.getTotalCount(),
|
__extends(ProductView, _BaseView);
|
||||||
'cost': this.collection.getTotalCost()
|
function ProductView() {
|
||||||
})).animate({paddingTop: '30px'})
|
ProductView.__super__.constructor.apply(this, arguments);
|
||||||
.animate({paddingTop: '10px'});
|
}
|
||||||
}
|
ProductView.prototype.id = 'productitemview';
|
||||||
});
|
ProductView.prototype.template = $("#store_item_template").html();
|
||||||
|
ProductView.prototype.initialize = function(options) {
|
||||||
var BackboneStore = Backbone.Router.extend({
|
this.constructor.__super__.initialize.apply(this, [options]);
|
||||||
views: {},
|
this.itemcollection = options.itemcollection;
|
||||||
products: null,
|
this.item = this.itemcollection.getOrCreateItemForProduct(this.model);
|
||||||
cart: null,
|
return this;
|
||||||
|
};
|
||||||
routes: {
|
ProductView.prototype.events = {
|
||||||
"": "index",
|
"keypress .uqf": "updateOnEnter",
|
||||||
"item/:id": "product",
|
"click .uq": "update"
|
||||||
},
|
};
|
||||||
|
ProductView.prototype.update = function(e) {
|
||||||
initialize: function(data) {
|
e.preventDefault();
|
||||||
this.cart = new ItemCollection();
|
return this.item.update(parseInt(this.$('.uqf').val()));
|
||||||
new CartWidget({collection: this.cart});
|
};
|
||||||
|
ProductView.prototype.updateOnEnter = function(e) {
|
||||||
this.products = new ProductCollection([], {
|
if (e.keyCode === 13) {
|
||||||
url: 'data/items.json'});
|
return this.update(e);
|
||||||
this.views = {
|
}
|
||||||
'_index': new ProductListView({
|
};
|
||||||
collection: this.products
|
ProductView.prototype.render = function() {
|
||||||
})
|
this.el.html(_.template(this.template, this.model.toJSON()));
|
||||||
};
|
return this;
|
||||||
$.when(this.products.fetch({reset: true}))
|
};
|
||||||
.then(function() { window.location.hash = ''; });
|
return ProductView;
|
||||||
return this;
|
})();
|
||||||
},
|
CartWidget = (function() {
|
||||||
|
__extends(CartWidget, Backbone.View);
|
||||||
hideAllViews: function () {
|
function CartWidget() {
|
||||||
return _.select(
|
CartWidget.__super__.constructor.apply(this, arguments);
|
||||||
_.map(this.views, function(v) { return v.hide(); }),
|
}
|
||||||
function (t) { return t != null });
|
CartWidget.prototype.el = $('.cart-info');
|
||||||
},
|
CartWidget.prototype.template = $('#store_cart_template').html();
|
||||||
|
CartWidget.prototype.initialize = function() {
|
||||||
index: function() {
|
return this.collection.bind('change', _.bind(this.render, this));
|
||||||
var view = this.views['_index'];
|
};
|
||||||
$.when(this.hideAllViews()).then(
|
CartWidget.prototype.render = function() {
|
||||||
function() { return view.show(); });
|
var tel;
|
||||||
},
|
tel = this.el.html(_.template(this.template, {
|
||||||
|
'count': this.collection.getTotalCount(),
|
||||||
product: function(id) {
|
'cost': this.collection.getTotalCost()
|
||||||
var product, v, view;
|
}));
|
||||||
product = this.products.detect(function(p) { return p.get('id') == (id); })
|
tel.animate({
|
||||||
view = ((v = this.views)['item.' + id]) || (v['item.' + id] = (
|
paddingTop: '30px'
|
||||||
new ProductView({model: product,
|
}).animate({
|
||||||
itemcollection: this.cart}).render()));
|
paddingTop: '10px'
|
||||||
$.when(this.hideAllViews()).then(
|
});
|
||||||
function() { view.show(); });
|
return this;
|
||||||
}
|
};
|
||||||
});
|
return CartWidget;
|
||||||
|
})();
|
||||||
$(document).ready(function() {
|
BackboneStore = (function() {
|
||||||
new BackboneStore();
|
__extends(BackboneStore, Backbone.Router);
|
||||||
Backbone.history.start();
|
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);
|
}).call(this);
|
||||||
|
|
Loading…
Reference in New Issue