关键词:Angular.js、购物车、前端开发、数据绑定、MVC架构、电子商务、单页应用
摘要:本文详细介绍了如何使用Angular.js框架实现电子商务网站中的购物车功能。我们将从Angular.js的核心概念入手,逐步构建一个完整的购物车系统,包括商品展示、添加/删除商品、数量修改、价格计算等功能。文章将深入探讨Angular.js的数据绑定机制、控制器设计、服务封装等关键技术点,并提供完整的代码实现和实际应用场景分析。
本文旨在为前端开发者提供一个使用Angular.js实现购物车功能的完整指南。我们将覆盖从基础概念到实际实现的全部过程,包括:
本文适合以下读者:
文章将按照以下结构组织:
Angular.js采用MVC架构模式,将应用分为三个主要部分:
购物车系统通常包含以下组件:
在Angular.js中实现购物车的数据流如下:
购物车需要存储以下信息:
// 示例商品对象
{
id: 1,
name: "AngularJS书籍",
price: 59.99,
quantity: 1,
subtotal: function() {
return this.price * this.quantity;
}
}
购物车服务是核心业务逻辑的封装:
app.service('CartService', function() {
var cart = [];
return {
addItem: function(item) {
// 检查是否已存在
var found = _.find(cart, {id: item.id});
if (found) {
found.quantity += item.quantity;
} else {
cart.push(angular.copy(item));
}
},
removeItem: function(item) {
var index = _.findIndex(cart, {id: item.id});
if (index !== -1) {
cart.splice(index, 1);
}
},
updateQuantity: function(item, newQuantity) {
var found = _.find(cart, {id: item.id});
if (found) {
found.quantity = newQuantity;
}
},
getCart: function() {
return cart;
},
getTotal: function() {
var total = 0;
angular.forEach(cart, function(item) {
total += item.subtotal();
});
return total;
},
clearCart: function() {
cart = [];
}
};
});
商品列表控制器和购物车控制器的实现:
app.controller('ProductListCtrl', function($scope, CartService) {
$scope.products = [
{id: 1, name: "AngularJS书籍", price: 59.99},
{id: 2, name: "JavaScript高级编程", price: 49.99},
{id: 3, name: "HTML5权威指南", price: 39.99}
];
$scope.addToCart = function(product) {
CartService.addItem({
id: product.id,
name: product.name,
price: product.price,
quantity: 1
});
};
});
app.controller('CartCtrl', function($scope, CartService) {
$scope.cart = CartService.getCart();
$scope.total = CartService.getTotal();
$scope.$watch(function() {
return CartService.getCart();
}, function(newVal) {
$scope.cart = newVal;
$scope.total = CartService.getTotal();
}, true);
$scope.removeItem = function(item) {
CartService.removeItem(item);
};
$scope.updateQuantity = function(item, newQuantity) {
if (newQuantity > 0) {
CartService.updateQuantity(item, newQuantity);
} else {
CartService.removeItem(item);
}
};
});
购物车的核心计算包括:
如果需要实现折扣功能,可以扩展模型:
d i s c o u n t e d T o t a l = t o t a l × ( 1 − d i s c o u n t R a t e ) discountedTotal = total \times (1 - discountRate) discountedTotal=total×(1−discountRate)
其中 d i s c o u n t R a t e discountRate discountRate是折扣率,如0.1表示10%折扣。
常见的运费计算模型:
s h i p p i n g = { 0 if t o t a l ≥ f r e e S h i p p i n g T h r e s h o l d b a s e S h i p p i n g + p e r I t e m S h i p p i n g × n u m b e r O f I t e m s otherwise shipping = \begin{cases} 0 & \text{if } total \geq freeShippingThreshold \\ baseShipping + perItemShipping \times numberOfItems & \text{otherwise} \end{cases} shipping={0baseShipping+perItemShipping×numberOfItemsif total≥freeShippingThresholdotherwise
其中:
mkdir angular-cart
cd angular-cart
npm init -y
npm install angular lodash angular-route bootstrap --save
完整的HTML结构:
DOCTYPE html>
<html ng-app="shoppingCart">
<head>
<title>AngularJS购物车title>
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.min.css">
<script src="node_modules/angular/angular.min.js">script>
<script src="node_modules/lodash/lodash.min.js">script>
<script src="app.js">script>
head>
<body>
<div class="container">
<h1>商品列表h1>
<div ng-controller="ProductListCtrl">
<div class="row">
<div class="col-md-4" ng-repeat="product in products">
<div class="panel panel-default">
<div class="panel-body">
<h3>{{product.name}}h3>
<p>价格: {{product.price | currency}}p>
<button class="btn btn-primary" ng-click="addToCart(product)">
加入购物车
button>
div>
div>
div>
div>
div>
<h1>购物车h1>
<div ng-controller="CartCtrl">
<div ng-if="cart.length === 0">
购物车为空
div>
<table class="table" ng-if="cart.length > 0">
<thead>
<tr>
<th>商品名称th>
<th>单价th>
<th>数量th>
<th>小计th>
<th>操作th>
tr>
thead>
<tbody>
<tr ng-repeat="item in cart">
<td>{{item.name}}td>
<td>{{item.price | currency}}td>
<td>
<input type="number" ng-model="item.quantity"
min="1" ng-change="updateQuantity(item, item.quantity)">
td>
<td>{{item.subtotal() | currency}}td>
<td>
<button class="btn btn-danger" ng-click="removeItem(item)">
删除
button>
td>
tr>
tbody>
<tfoot>
<tr>
<td colspan="3">总计td>
<td colspan="2">{{total | currency}}td>
tr>
tfoot>
table>
div>
div>
body>
html>
完整的app.js实现:
var app = angular.module('shoppingCart', []);
app.service('CartService', function() {
var cart = [];
return {
addItem: function(item) {
var found = _.find(cart, {id: item.id});
if (found) {
found.quantity += item.quantity;
} else {
var newItem = angular.copy(item);
newItem.subtotal = function() {
return this.price * this.quantity;
};
cart.push(newItem);
}
},
removeItem: function(item) {
var index = _.findIndex(cart, {id: item.id});
if (index !== -1) {
cart.splice(index, 1);
}
},
updateQuantity: function(item, newQuantity) {
var found = _.find(cart, {id: item.id});
if (found) {
found.quantity = newQuantity;
}
},
getCart: function() {
return cart;
},
getTotal: function() {
var total = 0;
angular.forEach(cart, function(item) {
total += item.subtotal();
});
return total;
},
clearCart: function() {
cart = [];
}
};
});
app.controller('ProductListCtrl', ['$scope', 'CartService',
function($scope, CartService) {
$scope.products = [
{id: 1, name: "AngularJS书籍", price: 59.99},
{id: 2, name: "JavaScript高级编程", price: 49.99},
{id: 3, name: "HTML5权威指南", price: 39.99}
];
$scope.addToCart = function(product) {
CartService.addItem({
id: product.id,
name: product.name,
price: product.price,
quantity: 1
});
};
}]);
app.controller('CartCtrl', ['$scope', 'CartService',
function($scope, CartService) {
$scope.cart = CartService.getCart();
$scope.total = CartService.getTotal();
$scope.$watch(function() {
return CartService.getCart();
}, function(newVal) {
$scope.cart = newVal;
$scope.total = CartService.getTotal();
}, true);
$scope.removeItem = function(item) {
CartService.removeItem(item);
};
$scope.updateQuantity = function(item, newQuantity) {
if (newQuantity > 0) {
CartService.updateQuantity(item, newQuantity);
} else {
CartService.removeItem(item);
}
};
}]);
模块定义:
CartService服务:
ProductListCtrl控制器:
CartCtrl控制器:
数据绑定:
事件处理:
购物车是电子商务网站的核心组件,适用于:
也可应用于非电商场景:
基于基本购物车可以扩展:
虽然Angular.js已被Angular(2+)取代,但在许多遗留系统中仍在使用。理解Angular.js的核心概念对于学习现代前端框架仍有价值。
对于现有Angular.js项目:
A: Angular.js(1.x)和Angular(2+)是完全不同的框架。Angular是重写的版本,使用组件化架构和TypeScript。
A: 可以采取以下措施:
A: 可以通过以下方式:
A: 在多人协作场景下:
A: 可以使用以下工具:
通过本文的学习,您应该已经掌握了使用Angular.js实现购物车功能的核心技术。虽然Angular.js不再是主流选择,但理解其设计思想和实现原理对于学习现代前端框架仍有重要价值。建议在实际项目中根据团队技术栈选择合适的框架,并将这些核心概念应用到新的技术环境中。