先来看看效果图:
购物车
一、代码
如果看了这个效果有兴趣想知道怎么做出来的话,那就继续往下看吧。话不多少,直接上代码。
html代码:
购物车
AngularJS实现购物车
序号
商品信息
单价(元)
数量
金额(元)
操作
{{$index + 1}}
{{item.title}}
{{item.price|number:2}}
{{item.price*item.quantity|number:2}}
购物车空空,快去寻找宝贝
已选商品:{{getQuantites()}}
合计:
{{getTotalAmount()|number:2}}
{{getTotalAmount()*discount|number:2}}(9折)
({{getTotalAmount()|number:2}})
js代码:
/ 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实现购物车"); }
}]);
二、分析
请忽略bootstrap的样式,我们只关注Angular,代码很简单,我们来简单的分析一下:
1. 准备
首先我们我们定义了一个
cart
模块、
cartCtr
控制器,并将它们引入到了html代码中,同时我们还在js中定义了一个数组
items
用于模拟购物车内的东西。
2. ng-repeat迭代器
为了将
items
里的数据动态的遍历加载出来,我们使用Angular里的内置指令
ng-repeat
,它可以非常方便的遍历数组,生成
DOM
元素,在这里循环生成了4个
标签:
item
就是
items
数组里面的某一个对象,是不是感觉这就是js中的
for/in
循环~~如果你是一名.net开发人员,用过asp.net mvc的Razor就对这种其他语言无缝操作
DOM
元素很熟悉了,至于java、PHP是否有没有类似的语法我就不清楚了,我是一名苦逼的.net开发。
ng-repeat迭代器
我们可以看到第一个td中用到了
$index
,这是
ng-repeat
内的,并不是我们定义的,它的值是当前
item
在
items
中的索引,从0开始,所以我们用
$index+1
作为序号,其他的还有(类似
item
.
linkUrl
)数据绑定。
我们在单价和金额两列用到了{{ xxx|number:2}},这是Angular中的一种过滤器,作用是将前面的值xxx保留两位小数,金额嘛,我们当然要精确一些。刚才说了这是一种过滤器,那就还有其他的,比如
currency
,可以在xxx前面添加一个$符号表示美元,可以自行百度其他过滤器用法。
3. 添加事件
当前界面上分别有数量+、-按钮、删除按钮,这几个事件都比较简单,利用
ng-click
给元素添加点击事件。通过传递某个商品的id,找到这个商品,对这个商品进行加、减、删除操作,只不过在“-”按钮上有添加了一个
ng-disabled
标签,根据名字我们就可以很容易想到html的
disabled
属性,它的作用就是当
ng-disabled
的值为true时
DOM
元素禁用,同理,下面用到的
ng-show
也是一样的,true时显示,false时隐藏。如果是数字的话会自动转化为
boolean
值,0是false,非0是true,注意负数也是true!。这里我让当数量为1时就不能减少了,因为再少就可以直接删除了呀~
然后在input元素添加
ng-keydown
事件,使其只能输入方向键↑→ ↓←、数字键、
backspace
。然后我试了下确实到达了目的,但是却可以输入类似“00021”这种数字,显然这并不能令人满意。我看了看淘宝的购物车,发现当在前面输入0时,这个文本框的内容会自动刷新,去掉前面的0,于是我又添加了
ng-keyup
事件:
$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);
}};
这时当我输入0时,文本框值就会自动刷新,为什么不添加到
keydown
里面而要另外再加一个事件呢?那是因为触发
keydown
事件时
target.value
的值还是原来的值,还没有包含本次输入的按键,而在
keydown
之后值就是新值了,这时候我们接着让触发
keyup
事件就可以达到目的了,可以对照看下淘宝购物车的效果,我觉得我的体验比它的更好,因为它只要不是在最后输入数字文本框总是会失去焦点。。。
4. 统计
统计数量就是直接绑定方法,遍历数组返回值。
合计金额这块,我做了个满15000打9折的设计。利用
ng-show
隐藏显示带打折信息的合计金额。
三、总结
js中用到了几处
forEach
遍历数组,ECMAScript5中原生的方法是
array.forEach(function(item,index,array){});
angular中也封装了,
angular.forEach(array,function(item,index,array){});
代码中我两种方法都用到了,也不知道那种性能好。。
至此,购物车就已经完成了,利用Angular的双向绑定,可以快速的实现数量、金额的联动改变。希望这篇文章的内容对大家学习和使用Angular能有所帮助,如果有疑问可以留言交流。
您可能感兴趣的文章:
使用Angular.js实现简单的购物车功能
Angularjs 制作购物车功能实例代码
Angular实现购物车计算示例代码
angular和BootStrap3实现购物车功能
AngularJS 购物车全选/取消全选功能的实现方法
angular.js实现购物车功能
angularjs实现简单的购物车功能
AngularJS 实现购物车全选反选功能
AngularJs 终极购物车(实例讲解)
Angular动画实现的2种方式以及添加购物车动画实例代码
相关文章
