Let’s take a look at the renderings first:
Shopping cart
1. Code
If you are interested in knowing how to do this after reading this effect, then continue reading. Not much, just upload the code.
html code:
<!DOCTYPE html><html lang="en" ng-app="cart"><head> <meta charset="UTF-8"> <title>Shopping cart</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 ng-show="items.length"> <caption>AngularJS Implementation Cart</caption> <tr> <th>Serial number</th> <th>Product information</th> <th>Unit price (yuan)</th> <th>Quantity</th> <th>Amount (yuan)</th> <th>Operation</th> </tr> <tr ng-repeat=" item in items"> <td>{{$index + 1}}</td> <td><a href="{{item.linkUrl}}" target="_blank">{{item.title}}</a></td> <td>{{item.price|number:2}}</td> <td> <button type="button" 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" ng-click="add(item.id)">+</button> </td> <td>{{item.price*item.quantity|number:2}}</td> <td> <button type="button" ng-click="delete(item.id)">Delete</button> </td> </tr></table><div ng-show="!items.length">The shopping cart is empty, go find the baby</div><div> Selected products: <span>{{getQuantites()}} </span> Total: <span ng-show="getTotalAmount()<15000">{{getTotalAmount()|number:2}}</span> <span ng-show="getTotalAmount()>=15000"> {{getTotalAmount()*discount|number:2}}<span>(10% off)</span> <span>({{getTotalAmount()|number:2}})</span> </span> <button type="button" ng-click="alertSubmit()">Checkout</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: "The self-cultivation fruit of Web full-stack engineer", 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 inches", 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 independent graphics card",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--; } }) }; //Add keydown event in the input box to avoid inputting non-positive integer $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) { //Arrow key↑→ ↓←, numeric keys, backspace } else { console.log(keycode); event.preventDefault(); return false; } };//keyup event, when the input number is 0, refresh the text box content $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); }}; //Delete the item $scope.delete = function (id) { $scope.items.forEach(function (item, index) { if (item.id == id) { if (confirm("Confirm to delete this item from the shopping cart?")) { $scope.items.splice(index, 1); return; } } } }) }; //Calculate the quantity of selected items $scope.getQuantites = function () { var quantities = 0; angular.forEach($scope.items, function (item, index, array) { if (item.quantity) { quantities += parseInt(item.quantity); } }); return quantities; }; //Calculate the total amount $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 implements shopping cart"); }}]);2. Analysis
Please ignore the style of bootstrap. We only focus on Angular. The code is very simple. Let’s briefly analyze it:
1. Prepare
First we define a cart module, cartCtr controller, and introduce them into the html code. At the same time, we also define an array items in js to simulate things in the shopping cart.
2. ng-repeat iterator
In order to dynamically traverse the data in items , we use the built-in instruction ng-repeat in Angular, which can easily traverse the array and generate DOM elements. Here we loop to generate 4 <tr> tags:
<tr ng-repeat=" item in items">
item is an object in the items array. Do you feel that this is for/in loop in js?~If you are a .net developer and have used asp.net mvc Razor, you are familiar with seamless operation of DOM elements in other languages. As for whether java and PHP have similar syntax, I don't know. I am a hard-working .net developer.
ng-repeat iterator
We can see $index is used in the first td, which is in ng-repeat , not what we define. Its value is the index of the current item in items , starting from 0, so we use $index+1 as the sequence number, and 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 keep the previous value xxx two decimal places. As for the amount, we must of course be more accurate. I just said that this is a filter, so there are other things, such as currency . You can add a $ symbol in front of xxx to represent US dollars, and you can use other filters on Baidu by yourself.
3. Add events
There are number +, - buttons and delete buttons on the current interface. These events are relatively simple. Use ng-click to add click events to the element. By passing the id of a certain product, find the product, and add, subtract and delete the product. However, an ng-disabled tag is added to the "-" button. According to the name, we can easily think of the disabled attribute of html. Its function is to disable DOM element when the value of ng-disabled is true. Similarly, ng-show used below is the same. It is displayed when true, and hidden when false. If it is a number, it will automatically convert to a boolean value. 0 is false, non-0 is true. Note that negative numbers are also true! . Here I will let the number of 1 not be reduced, because if the number is smaller, it can be deleted directly~
Then add the ng-keydown event to the input element so that it can only enter the arrow keys ↑→ ↓←, number keys, and backspace . Then I tried and did achieve the goal, but I could enter numbers like "00021", which obviously was not satisfactory. I looked at Taobao's shopping cart and found that when 0 is entered in front, the content of this text box will automatically refresh, removing the previous 0, so I added the ng-keyup event:
$scope.quantityKeyup = function (event) { event = event || window.event; //Compatible with IE8 or below, target is also var target=event.target||event.srcElement; var keycode = event.keyCode; if (48 === keycode || 96 === keycode ) { target.value=parseInt(target.value); }}; At this time, when I enter 0, the text box value will automatically refresh. Why not add it to keydown but add another event? That's because the value of target.value is still the original value when keydown event is triggered, and the key input is not included. After keydown , the value is the new value. At this time, we can then trigger keyup event to achieve our goal. We can compare the effect of Taobao shopping cart. I think my experience is better than it, because as long as it is not entered at the end, the text box will always lose focus. . .
4. Statistics
Statistical quantity is to directly bind the method and traverse the array to return the value.
For the total amount, I made a design that is 10% off for the total amount of 15,000. Use ng-show to hide the total amount of discounted information.
3. Summary
Several forEach traversal arrays are used in js. The native method in ECMAScript5 is array.forEach(function(item,index,array){});
angular is also encapsulated, angular.forEach(array,function(item,index,array){});
I used both methods in the code, and I don't know which one has good performance. .
At this point, the shopping cart has been completed. Using Angular's two-way binding, you can quickly achieve the linkage change of quantity and amount. I hope the content of this article will be helpful to everyone's learning and using Angular. If you have any questions, you can leave a message to communicate.