站长资源网络编程

利用Angularjs和bootstrap实现购物车功能

整理:jimmy2026/8/3浏览2
简介先来看看效果图:购物车一、代码如果看了这个效果有兴趣想知道怎么做出来的话,那就继续往下看吧。话不多少,直接上代码。html代码:购</div> <div class="news_infos"><div id="MyContent"><p><strong>先来看看效果图:</strong></p> <p><a href="javascript:;" onclick="showimg('/UploadFiles/2021-04-02/2016831113213288.png');"><img src="/UploadFiles/2021-04-02/2016831113213288.png" alt="利用Angularjs和bootstrap实现购物车功能" onmousewheel="return bbimg(this)" onload="javascript:resizepic(this)" border="0"/></a><br> 购物车</p> <p><strong>一、代码</strong></p> <p>如果看了这个效果有兴趣想知道怎么做出来的话,那就继续往下看吧。话不多少,直接上代码。</p> <p><strong>html代码:</strong></p> <div class="htmlcode"> <pre class="brush:xhtml;"> <!DOCTYPE html> <html lang="en" 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 class="bold">{{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 class="empty" ng-show="!items.length">购物车空空,快去寻找宝贝</div> <div class="total"> 已选商品:<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 class="discount">({{getTotalAmount()|number:2}})</span> </span> <button type="button" class="btn btn-primary btn-sm" ng-click="alertSubmit()">结 算</button> </div> <script src="/UploadFiles/2021-04-02/angular.js"> <p><strong>js代码:</strong><br> </p> <div class="htmlcode"> <pre class="brush: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"}, {id: 10002,title: "MacBook Pro Retina 15英寸", price: 16088.00,quantity: 1,linkUrl: "https://detail.tmall.com/item.htm"}, {id: 10003,title: "Surface Book I5 128G 独显",price: 11088.00, quantity: 1,linkUrl: "https://detail.tmall.com/item.htm"}, {id: 10004, title: "Lenovo Yoga3Pro I5 4G",price: 7299.00, quantity: 1,linkUrl: "https://detail.tmall.com/item.htm"} ]; $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实现购物车"); } }]);</pre> </div> <p><strong>二、分析</strong><br> </p> <p>请忽略bootstrap的样式,我们只关注Angular,代码很简单,我们来简单的分析一下:</p> <p><strong>1. 准备</strong><br> </p> <p>首先我们我们定义了一个<code>cart</code>模块、<code>cartCtr</code>控制器,并将它们引入到了html代码中,同时我们还在js中定义了一个数组<code>items</code>用于模拟购物车内的东西。</p> <p><strong>2. ng-repeat迭代器</strong><br> </p> <p>为了将<code>items</code>里的数据动态的遍历加载出来,我们使用Angular里的内置指令<code>ng-repeat</code>,它可以非常方便的遍历数组,生成<code>DOM</code>元素,在这里循环生成了4个<code><tr></code>标签:<br> </p> <div class="htmlcode"> <pre class="brush:xhtml;">   <tr ng-repeat=" item in items"></pre> </div> <p><code>item</code>就是<code>items</code>数组里面的某一个对象,是不是感觉这就是js中的<code>for/in</code>循环~~如果你是一名.net开发人员,用过asp.net mvc的Razor就对这种其他语言无缝操作<code>DOM</code>元素很熟悉了,至于java、PHP是否有没有类似的语法我就不清楚了,我是一名苦逼的.net开发。</p> <p><a href="javascript:;" onclick="showimg('/UploadFiles/2021-04-02/2016831113407515.png');"><img src="/UploadFiles/2021-04-02/2016831113407515.png" alt="利用Angularjs和bootstrap实现购物车功能" onmousewheel="return bbimg(this)" onload="javascript:resizepic(this)" border="0"/></a><br> ng-repeat迭代器</p> <p>我们可以看到第一个td中用到了<code>$index</code>,这是<code>ng-repeat</code>内的,并不是我们定义的,它的值是当前<code>item</code>在<code>items</code>中的索引,从0开始,所以我们用<code>$index+1</code>作为序号,其他的还有(类似<code>item</code>.<code>linkUrl</code>)数据绑定。<br> </p> <p>我们在单价和金额两列用到了{{ xxx|number:2}},这是Angular中的一种过滤器,作用是将前面的值xxx保留两位小数,金额嘛,我们当然要精确一些。刚才说了这是一种过滤器,那就还有其他的,比如<code>currency</code>,可以在xxx前面添加一个$符号表示美元,可以自行百度其他过滤器用法。</p> <p><strong>3. 添加事件</strong><br> </p> <p>当前界面上分别有数量+、-按钮、删除按钮,这几个事件都比较简单,利用<code>ng-click</code>给元素添加点击事件。通过传递某个商品的id,找到这个商品,对这个商品进行加、减、删除操作,只不过在“-”按钮上有添加了一个<code>ng-disabled</code>标签,根据名字我们就可以很容易想到html的<code>disabled</code>属性,它的作用就是当<code>ng-disabled</code>的值为true时<code>DOM</code>元素禁用,同理,下面用到的<code>ng-show</code>也是一样的,true时显示,false时隐藏。如果是数字的话会自动转化为<code>boolean</code>值,0是false,非0是true,注意负数也是true!。这里我让当数量为1时就不能减少了,因为再少就可以直接删除了呀~<br> </p> <p>然后在input元素添加<code>ng-keydown</code>事件,使其只能输入方向键↑→ ↓←、数字键、<code>backspace</code>。然后我试了下确实到达了目的,但是却可以输入类似“00021”这种数字,显然这并不能令人满意。我看了看淘宝的购物车,发现当在前面输入0时,这个文本框的内容会自动刷新,去掉前面的0,于是我又添加了<code>ng-keyup</code>事件:</p> <div class="htmlcode"> <pre class="brush:js;"> $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); }};</pre> </div> <p>这时当我输入0时,文本框值就会自动刷新,为什么不添加到<code>keydown</code>里面而要另外再加一个事件呢?那是因为触发<code>keydown</code>事件时<code>target.value</code>的值还是原来的值,还没有包含本次输入的按键,而在<code>keydown</code>之后值就是新值了,这时候我们接着让触发<code>keyup</code>事件就可以达到目的了,可以对照看下淘宝购物车的效果,我觉得我的体验比它的更好,因为它只要不是在最后输入数字文本框总是会失去焦点。。。</p> <p><strong>4. 统计</strong><br> </p> <p>统计数量就是直接绑定方法,遍历数组返回值。<br> </p> <p>合计金额这块,我做了个满15000打9折的设计。利用<code>ng-show</code>隐藏显示带打折信息的合计金额。</p> <p><strong>三、总结</strong><br> </p> <p>js中用到了几处<code>forEach</code>遍历数组,ECMAScript5中原生的方法是<code>array.forEach(function(item,index,array){});</code><br> </p> <p>angular中也封装了,<code>angular.forEach(array,function(item,index,array){});<br> </code></p> <p>代码中我两种方法都用到了,也不知道那种性能好。。<br> </p> <p>至此,购物车就已经完成了,利用Angular的双向绑定,可以快速的实现数量、金额的联动改变。希望这篇文章的内容对大家学习和使用Angular能有所帮助,如果有疑问可以留言交流。<br> </p></div> </div> </div> <div class="share"> </div> <div class="nextinfo"> <p>上一篇:<a href="/3g/1/105787.html" title="AngularJS实现一次监听多个值发生的变化">AngularJS实现一次监听多个值发生的变化</a></p> <p>下一篇:<a href="/3g/1/105789.html" title="JavaScript String(字符串)对象的简单实例(推荐)">JavaScript String(字符串)对象的简单实例(推荐)</a></p> </div> <div class="otherlink"> <h2>最新资源</h2> <ul> <li><a href="/3g/1/623703.html" title="群星《奔赴!万人现场 第2期》[FLAC/分轨]">群星《奔赴!万人现场 第2期》[FLAC/分轨]</a></li> <li><a href="/3g/1/623702.html" title="群星《奇妙浪一夏 (上海迪士尼度假区音乐">群星《奇妙浪一夏 (上海迪士尼度假区音乐</a></li> <li><a href="/3g/1/623701.html" title="群星《奇妙浪一夏 (上海迪士尼度假区音乐">群星《奇妙浪一夏 (上海迪士尼度假区音乐</a></li> <li><a href="/3g/1/623700.html" title="【古典音乐】詹姆斯·高威《季节》1993[WA">【古典音乐】詹姆斯·高威《季节》1993[WA</a></li> <li><a href="/3g/1/623699.html" title="贝拉芳蒂《卡里普索之王》SACD[WAV+CUE]">贝拉芳蒂《卡里普索之王》SACD[WAV+CUE]</a></li> <li><a href="/3g/1/623698.html" title="小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE">小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE</a></li> <li><a href="/3g/1/623697.html" title="群星《欢迎来到我身边 电影原声专辑》[32">群星《欢迎来到我身边 电影原声专辑》[32</a></li> <li><a href="/3g/1/623696.html" title="群星《欢迎来到我身边 电影原声专辑》[FL">群星《欢迎来到我身边 电影原声专辑》[FL</a></li> <li><a href="/3g/1/623695.html" title="雷婷《梦里蓝天HQⅡ》 2023头版限量编号低">雷婷《梦里蓝天HQⅡ》 2023头版限量编号低</a></li> <li><a href="/3g/1/623694.html" title="群星《2024好听新歌42》AI调整音效【WAV分">群星《2024好听新歌42》AI调整音效【WAV分</a></li> </ul> </div> </div> <div class="sidebar"> <div class="cloud"><h2 class="hometitle">标签云</h2><ul><a href="/search.asp?key=1080P高清&m=1">1080P高清<span>(5)</span></a><a href="/search.asp?key=高清电影&m=1">高清电影<span>(5)</span></a><a href="/search.asp?key=百度云盘&m=1">百度云盘<span>(5)</span></a><a href="/search.asp?key=网盘下载&m=1">网盘下载<span>(4)</span></a><a href="/search.asp?key=破解软件&m=1">破解软件<span>(4)</span></a><a href="/search.asp?key=绿色软件&m=1">绿色软件<span>(4)</span></a><a href="/search.asp?key=磁力链接&m=1">磁力链接<span>(3)</span></a><a href="/search.asp?key=强度天梯&m=1">强度天梯<span>(3)</span></a><a href="/search.asp?key=福利资源&m=1">福利资源<span>(2)</span></a><a href="/search.asp?key=王者荣耀&m=1">王者荣耀<span>(2)</span></a><a href="/search.asp?key=黑钻活动&m=1">黑钻活动<span>(2)</span></a><a href="/search.asp?key=WPS会员&m=1">WPS会员<span>(2)</span></a><a href="/search.asp?key=刷图排行&m=1">刷图排行<span>(1)</span></a><a href="/search.asp?key=网盘限速&m=1">网盘限速<span>(1)</span></a><a href="/search.asp?key=鬼灭之刃&m=1">鬼灭之刃<span>(1)</span></a><a href="/search.asp?key=免费韩国漫画&m=1">免费韩国漫画<span>(1)</span></a><a href="/search.asp?key=宫本重做&m=1">宫本重做<span>(1)</span></a><a href="/search.asp?key=免费动漫&m=1">免费动漫<span>(1)</span></a></ul></div> </div> <div class="sidebar"> 友情链接:<a href="http://www.imxmx.com/" title="杰晶网络" target="_blank">杰晶网络</a> <a href="/" title="DDR爱好者之家" target="_blank">DDR爱好者之家</a> <a href="http://www.nqxw.com/" title="南强小屋" target="_blank">南强小屋</a> <a href="http://www.paidiu.com/" title="黑松山资源网" target="_blank">黑松山资源网</a> <a href="http://www.dyhadc.com/" title="白云城资源网" target="_blank">白云城资源网</a> <a href="/sitemap1.xml">站点地图</a> <a href="/sitemap.xml">SiteMap</a> </div> </article> <footer> <p>Design by <a href="http://m.ddrfans.com">DDR爱好者之家</a> <a href="http://m.ddrfans.com">http://m.ddrfans.com</a></p> </footer> <script src="/images3g/nav.js"></script> <script type="text/javascript"> jQuery.noConflict(); jQuery(function() { var elm = jQuery('#left_flow2'); var startPos = jQuery(elm).offset().top; jQuery.event.add(window, "scroll", function() { var p = jQuery(window).scrollTop(); jQuery(elm).css('position', ((p) > startPos) ? 'fixed' : ''); jQuery(elm).css('top', ((p) > startPos) ? '0' : ''); }); }); </script> </body> </html>