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 相关文章推荐
javascript 面向对象编程基础:封装
Aug 21 Javascript
window.location.href = window.location.href 跳转无反应 a超链接onclick事件写法
Aug 21 Javascript
JavaScript 性能优化小结
Oct 12 Javascript
jquery插件之文字间歇自动向上滚动效果代码
Feb 25 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
Dec 13 Javascript
使用Bootstrap + Vue.js实现添加删除数据示例
Feb 27 Javascript
一道面试题引发的对javascript类型转换的思考
Mar 06 Javascript
Vue生命周期示例详解
Apr 12 Javascript
Node.js应用设置安全的沙箱环境
Apr 23 Javascript
JS简单生成由字母数字组合随机字符串示例
May 25 Javascript
Vue3.0结合bootstrap创建多页面应用
May 28 Javascript
vue.js实现数据库的JSON数据输出渲染到html页面功能示例
Aug 03 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防止表单重复提交的几种常用方法汇总
2014/08/19 PHP
浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
2015/10/26 PHP
php基于SQLite实现的分页功能示例
2017/06/21 PHP
PHP实现本地图片转base64格式并上传
2020/05/29 PHP
javascript 密码强弱度检测万能插件
2009/02/25 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
javascript Slip.js实现整屏滑动的手机网页
2015/11/25 Javascript
在axios中使用params传参的时候传入数组的方法
2018/09/25 Javascript
详解wepy开发小程序踩过的坑(小结)
2019/05/22 Javascript
vue-cli 项目打包完成后运行文件路径报错问题
2019/07/19 Javascript
JS阻止事件冒泡的方法详解
2019/08/26 Javascript
vue下的@change事件的实现
2019/10/25 Javascript
javascript跳转与返回和刷新页面的实例代码
2019/11/20 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
实例讲解Python中global语句下全局变量的值的修改
2016/06/16 Python
深入理解Python3中的http.client模块
2017/03/29 Python
python实现mysql的读写分离及负载均衡
2018/02/04 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
2019/06/25 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
Python3操作Excel文件(读写)的简单实例
2019/09/02 Python
利用Python代码实现一键抠背景功能
2019/12/29 Python
pytorch 实现打印模型的参数值
2019/12/30 Python
pycharm运行程序时看不到任何结果显示的解决
2020/02/21 Python
Pycharm远程连接服务器并实现代码同步上传更新功能
2020/02/25 Python
Keras 在fit_generator训练方式中加入图像random_crop操作
2020/07/03 Python
台湾深度自由行旅游平台:Tripbaa趣吧
2017/10/10 全球购物
家具促销活动方案
2014/02/16 职场文书
《一个小村庄的故事》教学反思
2014/04/13 职场文书
村级换届选举方案
2014/05/10 职场文书
绿色环保家庭事迹材料
2014/08/31 职场文书
统计学教授推荐信
2014/09/18 职场文书
2015年师德师风承诺书
2015/01/22 职场文书
民事二审代理词
2015/05/25 职场文书
军训后的感想
2015/08/07 职场文书
MySQL索引失效的典型案例
2021/06/05 MySQL