1. Code
If you are interested in seeing this effect and want to know how to make it, then continue reading. Not much to say, just go straight to the code.
html code:
<!DOCTYPE html> <html ng-app="cart"> <head> <meta charset="UTF-8"> <title>购物车</title> <link rel="stylesheet" href="../scripts/angular-1.4.0-rc.2/docs/components/bootstrap-3.1.1/css/bootstrap.min.css"> <link rel="stylesheet" href="main.css"> </head> <body ng-controller="cartCtr"> <table class="table table-hover" ng-show="items.length"> <caption>AngularJS实现购物车</caption> <tr> <th>序号</th> <th>商品信息</th> <th>单价(元)</th> <th>数量</th> <th>金额(元)</th> <th>操作</th> </tr> <tr ng-repeat=" item in items"> <td>{{$index + 1}}</td> <td><a href="{{item.linkUrl}}" target="_blank" title="此链接将跳转到淘宝相关页面...">{{item.title}}</a></td> <td>{{item.price|number:2}}</td> <td> <button type="button" class="btn btn-default btn-xs" ng-click="reduce(item.id)" ng-disabled="item.quantity<=1">-</button> <input type="text" size="5" ng-model="item.quantity" ng-keydown="quantityKeydown()" ng-keyup="quantityKeyup()"> <button type="button" class="btn btn-default btn-xs" ng-click="add(item.id)">+</button> </td> <td class="bold mark">{{item.price*item.quantity|number:2}}</td> <td> <button type="button" class="btn btn-default btn-xs" ng-click="delete(item.id)">删除</button> </td> </tr> </table> <div ng-show="!items.length">购物车空空,快去寻找宝贝</div> <div> 已选商品:<span>{{getQuantites()}} </span> 合计: <span class=" mark" ng-show="getTotalAmount()<15000">{{getTotalAmount()|number:2}}</span> <span class=" mark" ng-show="getTotalAmount()>=15000"> {{getTotalAmount()*discount|number:2}}<span class="btn btn-xs">(9折)</span> <span>({{getTotalAmount()|number:2}})</span> </span> <button type="button" class="btn btn-primary btn-sm" ng-click="alertSubmit()">结 算</button> </div> <script src="../scripts/angular-1.4.0-rc.2/angular.js"></script><script src="app.js"></script> </body> </html>
js code:
/ Created by wqq on 2016/5/25. / var cartModule = angular.module('cart', []); cartModule.controller('cartCtr', ['$scope', function ($scope) { $scope.discount = 0.9; $scope.items = [{id: 10001,title: "Web全栈工程师的自我修养 余果", price: 40.80,quantity: 2,linkUrl: "https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.4.cwywJs&id=532166746631"}, {id: 10002,title: "MacBook Pro Retina 15英寸", price: 16088.00,quantity: 1,linkUrl: "https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.26.cwywJs&id=45771116847"}, {id: 10003,title: "Surface Book I5 128G 独显",price: 11088.00, quantity: 1,linkUrl: "https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.15.cwywJs&id=525614504276"}, {id: 10004, title: "Lenovo Yoga3Pro I5 4G",price: 7299.00, quantity: 1,linkUrl: "https://detail.tmall.com/item.htm?spm=a1z0d.6639537.1997196601.37.cwywJs&id=41541519814"} ]; $scope.add = function (id) { angular.forEach($scope.items, function (item, index, array) { if (item.id === id) {item.quantity++;} }) }; $scope.reduce = function (id) { angular.forEach($scope.items, function (item, index, array) { if (item.id === id) {item.quantity--; } }) }; //输入框添加keydown事件,避免输入非正整数 $scope.quantityKeydown = function (event) { event = event || window.event; var target=event.target||event.srcElement; var keycode = event.keyCode; if ((37 <= keycode && keycode <= 40)||(48 <= keycode && keycode <= 57) || (96 <= keycode && keycode <= 105) || keycode == 8) { //方向键↑→ ↓←、数字键、backspace } else { console.log(keycode); event.preventDefault(); return false; } }; //keyup事件,当输入数字为0时,重新刷新文本框内容 $scope.quantityKeyup = function (event) { event = event || window.event; var target=event.target||event.srcElement; var keycode = event.keyCode; if (48 === keycode || 96 === keycode ) { target.value=parseInt(target.value); }}; //删除商品 $scope.delete = function (id) { $scope.items.forEach(function (item, index) { if (item.id == id) { if (confirm("确定要从购物车中删除此商品?")) { $scope.items.splice(index, 1); return; } } }) }; //计算已选商品数量 $scope.getQuantites = function () { var quantities = 0; angular.forEach($scope.items, function (item, index, array) { if (item.quantity) { quantities += parseInt(item.quantity); } }); return quantities; }; //计算合计总金额 $scope.getTotalAmount = function () { var totalAmount = 0; angular.forEach($scope.items, function (item, index, array) { totalAmount += item.quantity * item.price; }); return totalAmount; }; $scope.alertSubmit = function () {alert("Angular实现购物车"); } }]);
2. Analysis
Please ignore the bootstrap style, we only focus on Angular, code It's very simple, let's do a brief analysis:
1. Preparation
First we define a cart module and cartCtr controller, and introduce them into the html code. At the same time, we also defined an array items in js to simulate the contents of the shopping cart.
2. ng-repeat iterator
In order to dynamically traverse and load the data in items, we use the built-in instruction ng-repeat in Angular, which can be very convenient Traverse the array and generate DOM elements. Here, the loop generates 4
<tr ng-repeat=" item in items">
item is an object in the items array. Doesn’t it feel like this is the for/in loop in js~ ~If you are a .net developer and have used Razor of asp.net mvc, you will be familiar with the seamless operation of DOM elements in other languages. As for whether Java and PHP have similar syntax, I am not sure. I am a hardworking .net developer.
ng-repeat iterator
We can see that $index is used in the first td, which is within ng-repeat, not What we define is that its value is the index of the current item in items, starting from 0, so we use $index+1 as the serial number, and there are others (similar to item.linkUrl) data binding.
We used {{ xxx|number:2}} in the unit price and amount columns. This is a filter in Angular. Its function is to retain the previous value xxx to two decimal places. As for the amount, of course we have to be more precise. I just mentioned that this is a kind of filter, but there are others, such as currency. You can add a $ sign in front of xxx to represent the US dollar. You can Baidu other filter usages by yourself.
3. Add events
There are quantity +, - buttons, and delete buttons on the current interface. These events are relatively simple. Use ng-click to add click events to elements. . By passing the ID of a product, we can find the product and add, subtract, and delete the product. However, an ng-disabled tag is added to the "-" button. Based on the name, we can easily think of html. The disabled attribute, its function is to disable the DOM element when the value of ng-disabled is true. Similarly, the ng-show used below is the same. It is displayed when true and hidden when false. If it is a number, it will be automatically converted into a boolean value. 0 is false, non-0 is true, and note that negative numbers are also true! . Here I make it impossible to reduce the number when it is 1, because no matter how small it is, it can be deleted directly~
Then add the ng-keydown event to the input element so that only the direction keys can be input ↑ → ↓←, numeric keys, backspace. Then I tried it and achieved the goal, but I could enter numbers like "00021", which was obviously not satisfactory. I looked at Taobao's shopping cart and found that when I entered 0 in front, the content of this text box would automatically refresh and remove the previous 0, so I added the ng-keyup event:
$scope.quantityKeyup = function (event) { event = event || window.event; //兼容IE8以下,target也是 var target=event.target||event.srcElement; var keycode = event.keyCode; if (48 === keycode || 96 === keycode ) { target.value=parseInt(target.value); }};
When I enter 0, the text box value will automatically refresh. Why not add it to keydown but add another event? That's because when the keydown event is triggered, the value of target.value is still the original value, which does not include the key input this time. After keydown, the value is the new value. At this time, we can then trigger the keyup event to achieve the goal. You can check the effect of Taobao shopping cart. I think my experience is better than that, because the text box will always lose focus as long as the number is not entered at the end. . .
4. Statistics
The statistical quantity is a direct binding method that traverses the array and returns the value.
For the total amount, I made a design that offers a 10% discount for purchases over 15,000. Use ng-show to hide and display the total amount with discount information.
3. Summary
There are several forEach used in js to traverse arrays. The native method in ECMAScript5 is array.forEach(function(item,index,array){});
It is also encapsulated in angular, angular.forEach(array,function(item,index,array){});
I use both methods in the code When it arrives, I don’t know which performance is good. .
At this point, the shopping cart has been completed. Using Angular's two-way binding, you can quickly realize linked changes in quantity and amount. I hope the content of this article will be helpful to everyone in learning and using Angular. If you have any questions, you can leave a message to communicate.
For more related articles using Angularjs and bootstrap to implement the shopping cart function, please pay attention to the PHP Chinese website!