MVVM架構~knockoutjs實現簡單的購物車(che)
概念相關
購(gou)物(wu)車(che)相(xiang)信大(da)家都用(yong)過(guo),很方便,可以(yi)將(jiang)多個商品(pin)添加到購(gou)物(wu)車(che),并且可以(yi)修改購(gou)買商品(pin)的數(shu)據(ju),當然為(wei)了用(yong)戶體驗好,在(zai)修改數(shu)據(ju)時(shi),你的價格也會出現(xian)變化(hua)的,這使用(yong)JS可以(yi)實現(xian),但(dan)我認為(wei),代碼量挺(ting)大(da)的,而使用(yong)knockoutjs可以(yi)大(da)大(da)減少代碼量,而且更重要(yao)的是,當前臺頁面有所調整時(shi),這個JS只需(xu)要(yao)簡單(dan)調整,而不需(xu)要(yao)改后(hou)臺代碼!
代碼相關
下面看一下實現(xian)簡(jian)單購(gou)物車的(de)代碼
1 View部分
<table> <thead> <tr> <th>商品</th> <th>單價</th> <th>數量</th> <th>小計</th> <th></th> </tr> </thead> <tbody data-bind="foreach:lines"> <tr> <td data-bind="with:product"> <span data-bind="text:name"></span></td> <td data-bind="with:product"><span data-bind='text:formatCurrency(price)' /></td> <td> <input data-bind='visible: product, value: productCount, valueUpdate: "afterkeydown"' /> </td> <td><span data-bind="visible:product,text:formatCurrency(subtotal())"></span></td> <td><a href='#' data-bind='click: $parent.removeLine'>Remove</a></td> </tr> </tbody> </table> <p class='grandTotal'> Total value: <span data-bind='text: grandTotal()'></span> </p> <button data-bind='click: addLine'>Add product</button>
2 JS部分
<script type="text/ecmascript">
function formatCurrency(value) {
return "¥" + value;
}
var Product = function (id, name, price) {
self = this;
self.id = id;
self.name = name;
self.price = price;
}
var CartItem = function (product) {
self = this;
self.product = ko.observable(product);
self.productCount = ko.observable(1);
self.subtotal = ko.dependentObservable(function () {
return this.product() ? this.product().price * parseInt("0" + this.productCount(), 10) : 0;
}.bind(self));
};
var CartList = function () {
var self = this;
self.lines = ko.observableArray([new CartItem(new Product(1, "test1", 100))]);
self.addLine = function () { self.lines.push(new CartItem(new Product(2, "test2", 200))) };
self.removeLine = function (line) { self.lines.remove(line) };
self.grandTotal = ko.computed(function () {
var total = 0;
$.each(self.lines(), function () { total += this.subtotal(); })
return total;
});
};
ko.applyBindings(new CartList());
</script>
3 有圖有真相
完成代碼如下
<!DOCTYPE html> <html xmlns="//www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script src="jquery-1.7.1.min.js" type="text/javascript"></script> <script src="knockout-2.1.0.js" type="text/javascript"></script> </head> <body> <table> <thead> <tr> <th>商品</th> <th>單價</th> <th>數量</th> <th>小計</th> <th></th> </tr> </thead> <tbody data-bind="foreach:lines"> <tr> <td data-bind="with:product"> <span data-bind="text:name"></span></td> <td data-bind="with:product"><span data-bind='text:formatCurrency(price)' /></td> <td> <input data-bind='visible: product, value: productCount, valueUpdate: "afterkeydown"' /> </td> <td><span data-bind="visible:product,text:formatCurrency(subtotal())"></span></td> <td><a href='#' data-bind='click: $parent.removeLine'>Remove</a></td> </tr> </tbody> </table> <p class='grandTotal'> Total value: <span data-bind='text: grandTotal()'></span> </p> <button data-bind='click: addLine'>Add product</button> <script type="text/ecmascript"> function formatCurrency(value) { return "¥" + value; } var Product = function (id, name, price) { self = this; self.id = id; self.name = name; self.price = price; } var CartItem = function (product) { self = this; self.product = ko.observable(product); self.productCount = ko.observable(1); self.subtotal = ko.dependentObservable(function () { return this.product() ? this.product().price * parseInt("0" + this.productCount(), 10) : 0; }.bind(self)); }; var CartList = function () { var self = this; self.lines = ko.observableArray([new CartItem(new Product(1, "test1", 100))]); self.addLine = function () { self.lines.push(new CartItem(new Product(2, "test2", 200))) }; self.removeLine = function (line) { self.lines.remove(line) }; self.grandTotal = ko.computed(function () { var total = 0; $.each(self.lines(), function () { total += this.subtotal(); }) return total; }); }; ko.applyBindings(new CartList()); </script> </body> </html>
感謝您的閱讀!