Avalonjs 实现简单购物车功能(实例代码)


Posted in Javascript onFebruary 07, 2017

 先给大家简单介绍下avalon概念

avalon是国内最强大的MVVM框架,没有之一,虽然淘宝KISSY团队也搞了两个MVVM框架,但都无疾而终。其他的MVVM框架都没几个。也只有外国人与像我这样闲的架构师才有时间钻研这东西。我很早之前就预言,MVVM是前端的终极解决方案。我之前在盛大无线做盛大通行证就深有体会,一个业务逻辑对应十来个不同的界面,分层架构是必不可少的。因此双向绑定作为解药,结合很早就流行的MVC框架,衍生出MVVM这神器。

  因为最近有在做购物车,然后我们是用avalon来实现一些模块的,所以顺其自然的用avalon来实现购物车,目前发现avalon还是比较强大的,大大的节约了代码量。

    购物车一般具备的功能是加减数量、选择商品、删除商品和计算金额,因为avalon具有双向绑定功能,所以杜绝了dom的操作,只需要完成功能的逻辑即可,可以分下面几个步骤实现。

runjs: http://runjs.cn/detail/1dnkgxom

    1、页面的Html结构

    这里不考虑好的效果,所以直接用最简单的html来实现了,主要包含控制器,列表循环,金额显示,简单代码结构如下

<body ms-controller="test">
 <ul ms-visible="arr.length">
  <li><input type="checkbox"
 ms-click="checkAll" ms-duplex-checked="checkAllbool"/>全选</li>
  <li ms-repeat="arr"
 >
  <input type="checkbox"
 ms-attr-value="el.id" ms-duplex="selected" />
  {{el.text}}
  <input type="text"
 name="" ms-attr-value="el.num" ms-on-input="changeNum(el)">
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="plus(el)">加</a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="minus(el)">减</a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="del(el)">删除</a>
  <p>单价:{{el.price
 | currency}}</p>
  <p>金额:{{el.num*el.price
 | currency}}</p>
  </li>
 </ul>
 <p>总金额:{{total
 | currency}}</p>
 </body>

     这里有全选、加减、删除几个功能事件,金额用了过滤器currency。

    2、引入avalon.js,定义模型

    引入js是必须的,那么引入avalon.js后可以定义了

var vm
 = avalon.define({
  $id:
"test"
});

   这样就定义了一个简单的模型,$id传入的是控制器的值,本文例子的控制器是写在body,如果不理解可以去看看官网。

    3、定义购物车里面的商品

    实际项目中,这个肯定是通过后台获取到的,这里为了演示就直接定义了,从第一点的html结构可以看出来,这里购物车的商品用的是arr,所以接着定义的就是arr,可以这样定义

arr
 : [
 {
 id:1,
 num:1,
 price:45.5,
 text:'商品1'
 },
 {
 id:2,
 num:1,
 price:8.8,
 text:'商品2'
 }<span
 style="font-size:
 9pt; line-height: 1.5;">]</span>

    这里就定义两个用来测试,那么还需要一个值来保存选中的商品id,这里给模型增加一个selected属性,类型为数组

selected:[]

    4、定义全选的模型和方法

    购物车里面一般都有全选的功能的,只是表现的形式不一样,那么可以这么定义

checkAllbool
 : false,
checkAll
 : function()
 {
 if (this.checked)
 {
  var _arr
 = [];
  avalon.each(vm.arr,function(index,item){
   _arr[index]
 = item.id+'';
  });
  vm.selected
 = _arr;
 }
else {
  vm.selected=[];
 }
}

    通过checkAllbool属性来实现和判断是否选中“全选”,通过checkAll来实现选中全部或者取消选中全部,其实就是修改模型里面的selected属性,如果selected为空数组则没有一个是选中的,如果那个需要选中只需要把对应的值放到selected数组中即可,因为在html中checkbox使用 ms-duplex 进行绑定的,而绑定的是 selected属性。

     4、定义加、减、删除的方法

      加减主要是数量上的变化,而删除则是需要把该商品直接从arr(前面定义的属性)中删除

plus:
function(el){
 el.num++;
 vm.cal();
 },
minus:
function(el){
 if(el.num>1){
 el.num--;
 vm.cal();
 }
},
del:
function(el){
 vm.arr.remove(el);
},
changeNum:
function(el){
 var _value
 = this.value,
 _reg
 = /^[1-9]\d?$/
 ;
 if(!_reg.test(_value)){
 this.value
 = 1;
 el.num
 = 1;
 }else{
 el.num
 = _value;
 }
 vm.cal();
}

    这里还有一个是当输入框改变时执行的方法,这里通过出入对象来进行操作,可以看看第一步中的html代码,就明白了,无论是改变还是加减都最后要执行 vm.cal,vm.cal是计算总金额的,将在下面讲解。

    加减的方法都很简单主要是修改num属性即可,changeNum则增加了正则判断,判断输入的是否为数字。

    5、定义计算总金额

    计算总金额的方法很简单,就是把所有选中的商品的数量乘以单价再加起来,但是这里面涉及到另一个方法,那就是通过商品的id来找出对应的商品,这样才能计算该商品的金额。

total:0,
cal:
function(){
 var _arr
 = this.arr,
 _selected
 = this.selected,
 i
 = 0,
 _obj
 = '',
 _prcie
 = 0
 ;
 if(_selected.length){
 for(;i<_selected.length;i++){
  _obj
 = this.findById(_selected[i])
 ||{};
  if(_obj.price
 && _obj.num){
   _prcie
 = _prcie + _obj.price * _obj.num;
  }
 }
 }
 this.total
 = _prcie;
 },
findById:
function(id){
 if(!id)
return '';
 var i=0,
  _arr
 = this.arr,
  _obj
 = '',
  _id
 = parseInt(id,10)
 ;
  for(;i<_arr.length;i++){
  if(_arr[i].id
 === _id){
   _obj
 = _arr[i];
  }
 }
  return _obj;
}

    这里面主要用的是循环,找到商品的对象然后计算商品的金额再相加,代码略长。

    6、监听属性

    需要监听两个属性,那就是 selected 和 arr,监听 selected是为了随时了解商品有没有全选中,主要通过监听Length。监听arr是判断商品有没有被删除,如果arr的length改变,则表示商品有被删除,需要重新计算总金额。

vm.selected.$watch("length",
function(n)
 {
 vm.checkAllbool
 = n === vm.arr.size()
 vm.cal();
});
vm.arr.$watch("length",
function(n)
 {
 vm.cal();
});

    通过上面的步骤分析,可以了解了大概的实现流程,下面是完整的代码。

<!DOCTYPE html> <html>
 <head>
 <title>购物车</title>
 <meta http-equiv="Content-Type"
 content="text/html; charset=UTF-8">
 <meta http-equiv="X-UA-Compatible"
 content="IE=edge" /> 
 <script src="../avalon.js"
 ></script>
 <script>
  var
 vm = avalon.define({
  $id:
 "test",
  arr
 : [
   {
   id:1,
   num:1,
   price:45.5,
   text:'商品1'
   },
   {
   id:2,
   num:1,
   price:8.8,
   text:'商品2'
   }
  ],
  selected
 : ["1"],
  checkAllbool
 : false,
  checkAll
 : function() {
   if
 (this.checked) {
   var
 _arr = [];
   avalon.each(vm.arr,function(index,item){
    _arr[index]
 = item.id+'';
   });
   vm.selected
 = _arr;
   }
 else {
   vm.selected=[];
   }
  },
  plus:
 function(el){
   el.num++;
   vm.cal();
  },
  minus:
 function(el){
   if(el.num>1){
   el.num--;
   vm.cal();
   }
  },
  del:
 function(el){
   vm.arr.remove(el);
  },
  changeNum:
 function(el){
   var
 _value = this.value,
   _reg
 = /^[1-9]\d?$/
   ;
   if(!_reg.test(_value)){
   this.value
 = 1;
   el.num
 = 1;
   }else{
   el.num
 = _value;
   }
   vm.cal();
  },
  total:0,
  cal:
 function(){
   var
 _arr = this.arr,
   _selected
 = this.selected,
   i
 = 0,
   _obj
 = '',
   _prcie
 = 0
   ;
   if(_selected.length){
   for(;i<_selected.length;i++){
    _obj
 = this.findById(_selected[i]) ||{};
    if(_obj.price
 && _obj.num){
    _prcie
 = _prcie + _obj.price * _obj.num;
    }
   }
   }
   this.total
 = _prcie;
   },
  findById:
 function(id){
   if(!id)
 return '';
   var
 i=0,
   _arr
 = this.arr,
   _obj
 = '',
   _id
 = parseInt(id,10)
   ;
   for(;i<_arr.length;i++){
   if(_arr[i].id
 === _id){
    _obj
 = _arr[i];
   }
   }
   return
 _obj;
  }
  });
  vm.selected.$watch("length",
 function(n) {
  vm.checkAllbool
 = n === vm.arr.size()
  vm.cal();
  });
  vm.arr.$watch("length",
 function(n) {
  vm.cal();
  });
  vm.cal();
 </script>
 </head>
 <body ms-controller="test">
 <ul ms-visible="arr.length">
  <li><input type="checkbox"
 ms-click="checkAll" ms-duplex-checked="checkAllbool"/>全选</li>
  <li ms-repeat="arr"
 >
  <input type="checkbox"
 ms-attr-value="el.id" ms-duplex="selected" />
  {{el.text}}
  <input type="text"
 name="" ms-attr-value="el.num" ms-on-input="changeNum(el)">
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="plus(el)">加</a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="minus(el)">减</a>
  <a href="javascript:;" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
 ms-click="del(el)">删除</a>
  <p>单价:{{el.price
 | currency}}</p>
  <p>金额:{{el.num*el.price
 | currency}}</p>
  </li>
 </ul>
 <p>总金额:{{total
 | currency}}</p>
 </body>
</html>

    用avalon时间还不久,一步步来,希望能更深入了解mvvm框架,在后面的日子里应用更多的场景。

以上所述是小编给大家介绍的Avalonjs 实现简单购物车功能(实例代码),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery+ashx无刷新GridView数据显示插件(实现分页、排序、过滤功能)
Apr 25 Javascript
Ajax执行顺序流程及回调问题分析
Dec 10 Javascript
jQuery中ajax的load()与post()方法实例详解
Jan 05 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
Jan 14 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
May 15 Javascript
js判断价格,必须为数字且不能为负数的实现方法
Oct 07 Javascript
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Dec 14 Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
Jan 07 Javascript
vue实现简单的星级评分组件源码
Nov 16 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
Feb 28 jQuery
Nuxt.js实现一个SSR的前端博客的示例代码
Sep 06 Javascript
vue实现将一个数组内的相同数据进行合并
Nov 07 Javascript
深入理解JavaScript中的尾调用(Tail Call)
Feb 07 #Javascript
基于JavaScript实现下拉列表左右移动代码
Feb 07 #Javascript
原生JavaScript实现AJAX、JSONP
Feb 07 #Javascript
[原创]SyntaxHighlighter自动识别并加载脚本语言
Feb 07 #Javascript
javascript表达式和运算符详解
Feb 07 #Javascript
利用jQuery实现滑动开关按钮效果(附demo源码下载)
Feb 07 #Javascript
原生js和css实现图片轮播效果
Feb 07 #Javascript
You might like
php中实现xml与mysql数据相互转换的方法
2014/12/25 PHP
Thinkphp5行为使用方法汇总
2017/12/21 PHP
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
javascript 图片上一张下一张链接效果代码
2010/03/12 Javascript
jquery实现加载等待效果示例
2013/09/25 Javascript
jquery弹出层类代码分享
2013/12/27 Javascript
js浏览器本地存储store.js介绍及应用
2014/05/13 Javascript
JQuery基础语法小结
2015/02/27 Javascript
微信小程序 解决swiper不显示图片的方法
2017/01/04 Javascript
微信小程序 WebSocket详解及应用
2017/01/21 Javascript
angular中的cookie读写方法
2017/08/02 Javascript
jQuery实现的淡入淡出与滑入滑出效果示例
2018/04/18 jQuery
基于Koa(nodejs框架)对json文件进行增删改查的示例代码
2019/02/02 NodeJs
python 实现文件的递归拷贝实现代码
2012/08/02 Python
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
Python内置函数的用法实例教程
2014/09/08 Python
Python的Bottle框架中获取制定cookie的教程
2015/04/24 Python
Python自动生产表情包
2017/03/17 Python
修改默认的pip版本为对应python2.7的方法
2018/11/06 Python
pytorch 预训练层的使用方法
2019/08/20 Python
树莓派3 搭建 django 服务器的实例
2019/08/29 Python
python实现LRU热点缓存及原理
2019/10/29 Python
numpy按列连接两个维数不同的数组方式
2019/12/06 Python
pycharm设置当前工作目录的操作(working directory)
2020/02/14 Python
django的403/404/500错误自定义页面的配置方式
2020/05/21 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
2020/11/11 Python
HTML中使用SVG与SVG预定义形状元素介绍
2013/06/28 HTML / CSS
波兰最大的宠物用品网上商店:FERA.PL
2019/08/11 全球购物
美国折扣地毯销售网站:Rugs.com
2020/03/27 全球购物
.NET remoting的两种通道是什么
2016/05/31 面试题
农行实习自我鉴定
2013/09/22 职场文书
广告学专业毕业生自荐信
2013/09/24 职场文书
工程采购员岗位职责
2014/03/09 职场文书
工伤事故赔偿协议书
2014/10/27 职场文书
2014年师德师风工作总结
2014/11/25 职场文书
win10频率超出范围怎么办?win10老显示超出工作频率范围的解决方法
2022/07/07 数码科技