Fixed a bug with the updater.

This commit is contained in:
Elf M. Sternberg 2011-08-07 17:44:17 -07:00
parent e7625991a1
commit 58c3d50bce
5 changed files with 162 additions and 135 deletions

View File

@ -39,7 +39,7 @@ store.js: backbonestore.nw
rm $*.nw-tmp; \
fi
index.html:
index.html: backbonestore.nw
@ $(ECHO) $(NOTANGLE) -c -R$@ $<
@ - $(NOTANGLE) -c -R$@ $< > $*.nw-html-tmp
@ if [ -s "$*.nw-html-tmp" ]; then \

View File

@ -144,9 +144,11 @@ Also, it would be nice to know the total price of the Item.
<<cart models>>=
var Item = Backbone.Model.extend({
update: function(amount) {
this.set({'quantity': amount});
this.set({'quantity': amount}, {silent: true});
this.collection.trigger('change', this);
},
price: function() {
console.log(this.get('product').get('title'), this.get('quantity'));
return this.get('product').get('price') * this.get('quantity');
}
});
@ -236,7 +238,7 @@ and remove tabs from the top of the viewport as needed.
<<base view>>=
var _BaseView = Backbone.View.extend({
parent: '#main',
parent: $('#main'),
className: 'viewport',
@
@ -313,8 +315,8 @@ for our one-page application:
</title>
<link rel="stylesheet" href="jsonstore.css" type="text/css">
<<product list template>>
<<product template>>
<<checkout template>>
<<product detail template>>
<<cart template>>
</head>
<body>
<div id="container">
@ -398,10 +400,10 @@ And here is the HTML:
<img alt="<%= p.title %>" src="<%= p.image %>" />
</a>
</div>
</li>
<div class="item-artist"><%= p.artist %></div>
<div class="item-title"><%= p.title %></div>
<div class="item-price">$<%= p.price %></div>
</li>
<% } %>
</ul>
</script>
@ -467,12 +469,20 @@ get its id and so forth. All of that has been put into the shopping
cart model, which is where it belongs: \textit{knowledge about items
and each item's relationship to its collection belongs in the
collection}.
Look closely at the [[update()]] method. The reference [[this.\$]] is
a special Backbone object that limits selectors to objects inside the
element of the view. Without it, jQuery would have found the first
input field of class 'uqf' in the DOM, not the one for this specific
view. [[this.\$('.uqf')]] is shorthand for [[$('uqf', this.el)]], and
helps clarify what it is you're looking for.
%'
<<product detail view>>=
update: function(e) {
e.preventDefault();
this.item.update(parseInt($('.uqf').val()));
this.item.update(parseInt(this.$('.uqf').val()));
},
updateOnEnter: function(e) {
@ -722,6 +732,8 @@ Here's the entirety of the program:
<<product detail view>>
<<cart widget>>
<<router>>
<<initialization>>

View File

@ -1,9 +1,10 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>The Backbone Store</title>
<link charset="utf-8" href="jsonstore.css" rel="stylesheet" type="text/css" />
<title>
The Backbone Store
</title>
<link rel="stylesheet" href="jsonstore.css" type="text/css">
<script id="store_index_template" type="text/x-underscore-tmplate">
<h1>Product Catalog</h1>
<ul>
@ -14,24 +15,23 @@
<img alt="<%= p.title %>" src="<%= p.image %>" />
</a>
</div>
</li>
<div class="item-artist"><%= p.artist %></div>
<div class="item-title"><%= p.title %></div>
<div class="item-price">$<%= p.price %></div>
</li>
<% } %>
</ul>
</script>
<script id="store_item_template" type="text/x-underscore-template">
<div class="item-detail"></div>
<div class="item-detail">
<div class="item-image">
<img alt="<%= title %>" src="<%= large_image %>" />
</div>
<div class="item-info"></div>
</div>
<div class="item-info">
<div class="item-artist"><%= artist %></div>
<div class="item-title"><%= title %></div>
<div class="item-price">$<%= price %></div>
<div class="item-form"></div>
<form action="#/cart" method="post">
<p>
<label>Quantity:</label>
@ -47,22 +47,24 @@
<div class="back-link">
<a href="#">&laquo; Back to Items</a>
</div>
</div>
</script>
<script id="store_cart_template" type="text/x-underscore-template">
<p>Items: <%= count %> ($<%= cost %>)</p>
</script>
</head>
<body>
<div id="container">
<div id="header">
<h1>
The Backbone Store
</h1>
<div class="cart-info"></div>
<div class="cart-info">
</div>
</div>
<div id="main"> </div>
</div>
<script src="jquery-1.6.2.min.js" type="text/javascript"></script>

View File

@ -33,12 +33,17 @@ body {
img {
border: 0;
}
#productlistview ul {
list-style: none;
}
.item {
display: border;
float:left;
width: 250px;
margin-right: 3px;
padding: 2px;
margin-right: 10px;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ccc;
text-align:center;
font-size: 12px;

View File

@ -16,12 +16,18 @@
var Item = Backbone.Model.extend({
update: function(amount) {
this.set({'quantity': this.get('quantity') + amount});
this.set({'quantity': amount}, {silent: true});
this.collection.trigger('change', this);
},
price: function() {
console.log(this.get('product').get('title'), this.get('quantity'));
return this.get('product').get('price') * this.get('quantity');
}
});
var ItemCollection = Backbone.Collection.extend({
model: Item,
getOrCreateItemForProduct: function(product) {
var i,
pid = product.get('id'),
@ -35,18 +41,19 @@
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);
return obj.price() + memo; }, 0);
}
});
var _BaseView = Backbone.View.extend({
parent: $('#main'),
className: 'viewport',
@ -63,9 +70,8 @@
return null;
}
promise = $.Deferred(_.bind(function(dfd) {
this.el.fadeOut('fast', dfd.resolve)}, this)).promise();
this.trigger('hide', this);
return promise;
this.el.fadeOut('fast', dfd.resolve)}, this));
return promise.promise();
},
show: function() {
@ -73,13 +79,12 @@
return;
}
promise = $.Deferred(_.bind(function(dfd) {
this.el.fadeIn('fast', dfd.resolve) }, this)).promise();
this.trigger('show', this);
return promise;
this.el.fadeIn('fast', dfd.resolve) }, this))
return promise.promise();
}
});
var ProductListView = _BaseView.extend({
id: 'productlistview',
template: $("#store_index_template").html(),
@ -96,6 +101,7 @@
}
});
var ProductView = _BaseView.extend({
id: 'productitemview',
template: $("#store_item_template").html(),
@ -113,7 +119,7 @@
update: function(e) {
e.preventDefault();
this.item.update(parseInt($('.uqf').val()));
this.item.update(parseInt(this.$('.uqf').val()));
},
updateOnEnter: function(e) {
@ -128,6 +134,7 @@
}
});
var CartWidget = Backbone.View.extend({
el: $('.cart-info'),
template: $('#store_cart_template').html(),
@ -137,7 +144,6 @@
},
render: function() {
console.log(arguments);
this.el.html(
_.template(this.template, {
'count': this.collection.getTotalCount(),
@ -147,6 +153,7 @@
}
});
var BackboneStore = Backbone.Router.extend({
views: {},
products: null,
@ -200,4 +207,5 @@
new BackboneStore();
Backbone.history.start();
});
}).call(this);