蚂蚁论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 41|回复: 0

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

[复制链接]

1923

主题

1

好友

1591

积分

管理员

Rank: 64Rank: 64Rank: 64Rank: 64

  • TA的每日心情
    奋斗
    2016-1-22 16:23
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    荣誉管理 论坛元老 热心会员 活跃会员 最佳新人 灌水之王

    发表于 7 天前 |显示全部楼层
    Avalonjs 实现简单购物车功能(实例代码)
    先给大家简单介绍下avalon概念
    avalon是国内最强大的MVVM框架,没有之一,虽然淘宝KISSY团队也搞了两个MVVM框架,但都无疾而终。其他的MVVM框架都没几个。也只有外国人与像我这样闲的架构师才有时间钻研这东西。我很早之前就预言,MVVM是前端的终极解决方案。我之前在盛大无线做盛大通行证就深有体会,一个业务逻辑对应十来个不同的界面,分层架构是必不可少的。因此双向绑定作为解药,结合很早就流行的MVC框架,衍生出MVVM这神器。
    因为最近有在做购物车,然后我们是用avalon来实现一些模块的,所以顺其自然的用avalon来实现购物车,目前发现avalon还是比较强大的,大大的节约了代码量。
    购物车一般具备的功能是加减数量、选择商品、删除商品和计算金额,因为avalon具有双向绑定功能,所以杜绝了dom的操作,只需要完成功能的逻辑即可,可以分下面几个步骤实现。
      runjs: runjscn/detail/1dnkgxom
    1、页面的Html结构
    这里不考虑好的效果,所以直接用最简单的html来实现了,主要包含控制器,列表循环,金额显示,简单代码结构如下


    lt;body ms-controller="test"gt;
    lt;ul ms-visible="arrlength"gt;
      lt;ligt;lt;input type="checkbox"
    ms-click="checkAll" ms-duplex-checked="checkAllbool"/gt;全选lt;/ligt;
      lt;li ms-repeat="arr"
    gt;
      lt;input type="checkbox"
    ms-attr-value="elid" ms-duplex="selected" /gt;
      {{eltext}}
      lt;input type="text"
    name="" ms-attr-value="elnum" ms-on-input="changeNum(el)"gt;
      lt;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)"gt;加lt;/agt;
      lt;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)"gt;减lt;/agt;
      lt;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)"gt;删除lt;/agt;
      lt;pgt;单价:{{elprice
    | currency}}lt;/pgt;
      lt;pgt;金额:{{elnum*elprice
    | currency}}lt;/pgt;
      lt;/ligt;
    lt;/ulgt;
    lt;pgt;总金额:{{total
    | currency}}lt;/pgt;
    lt;/bodygt;

    这里有全选、加减、删除几个功能事件,金额用了过滤器currency。
    2、引入avalonjs,定义模型
    引入js是必须的,那么引入avalonjs后可以定义了


    var vm
    = avalondefine({
      $id:
    "test"
    });

    这样就定义了一个简单的模型,$id传入的是控制器的值,本文例子的控制器是写在body,如果不理解可以去看看官网。
    3、定义购物车里面的商品
    实际项目中,这个肯定是通过后台获取到的,这里为了演示就直接定义了,从第一点的html结构可以看出来,这里购物车的商品用的是arr,所以接着定义的就是arr,可以这样定义


    arr
    : [
    {
    id:1,
    num:1,
    price:455,
    text:'商品1'
    },
    {
    id:2,
    num:1,
    price:88,
    text:'商品2'
    }lt;span
    style="font-size:
    9pt; line-height: 15;"gt;]lt;/spangt;

    这里就定义两个用来测试,那么还需要一个值来保存选中的商品id,这里给模型增加一个selected属性,类型为数组
    selected:[]
    4、定义全选的模型和方法
    购物车里面一般都有全选的功能的,只是表现的形式不一样,那么可以这么定义


    checkAllbool
    : false,
    checkAll
    : function()
    {
    if (thischecked)
    {
      var _arr
    = [];
      avaloneach(vmarr,function(index,item){
       _arr[index]
    = itemid+'';
      });
      vmselected
    = _arr;
    }
    else {
      vmselected=[];
    }
    }

    通过checkAllbool属性来实现和判断是否选中“全选”,通过checkAll来实现选中全部或者取消选中全部,其实就是修改模型里面的selected属性,如果selected为空数组则没有一个是选中的,如果那个需要选中只需要把对应的值放到selected数组中即可,因为在html中checkbox使用 ms-duplex 进行绑定的,而绑定的是 selected属性。
    4、定义加、减、删除的方法
    加减主要是数量上的变化,而删除则是需要把该商品直接从arr(前面定义的属性)中删除


    plus:
    function(el){
    elnum++;
    vmcal();
    },
    minus:
    function(el){
    if(elnumgt;1){
    elnum--;
    vmcal();
    }
    },
    del:
    function(el){
    vmarrremove(el);
    },
    changeNum:
    function(el){
    var _value
    = thisvalue,
    _reg
    = /^[1-9]\d63;$/
    ;
    if(!_regtest(_value)){
    thisvalue
    = 1;
    elnum
    = 1;
    }else{
    elnum
    = _value;
    }
    vmcal();
    }

    这里还有一个是当输入框改变时执行的方法,这里通过出入对象来进行操作,可以看看第一步中的html代码,就明白了,无论是改变还是加减都最后要执行 vmcal,vmcal是计算总金额的,将在下面讲解。
    加减的方法都很简单主要是修改num属性即可,changeNum则增加了正则判断,判断输入的是否为数字。
    5、定义计算总金额
    计算总金额的方法很简单,就是把所有选中的商品的数量乘以单价再加起来,但是这里面涉及到另一个方法,那就是通过商品的id来找出对应的商品,这样才能计算该商品的金额。


    total:0,
    cal:
    function(){
    var _arr
    = thisarr,
    _selected
    = thisselected,
    i
    = 0,
    _obj
    = '',
    _prcie
    = 0
    ;
    if(_selectedlength){
    for(;ilt;_selectedlength;i++){
      _obj
    = thisfindById(_selected[i])
    ||{};
      if(_objprice
      _objnum){
       _prcie
    = _prcie + _objprice * _objnum;
      }
    }
    }
    thistotal
    = _prcie;
    },
    findById:
    function(id){
    if(!id)
    return '';
    var i=0,
      _arr
    = thisarr,
      _obj
    = '',
      _id
    = parseInt(id,10)
    ;
      for(;ilt;_arrlength;i++){
      if(_arr[i]id
    === _id){
       _obj
    = _arr[i];
      }
    }
      return _obj;
    }

    这里面主要用的是循环,找到商品的对象然后计算商品的金额再相加,代码略长。
    6、监听属性
    需要监听两个属性,那就是 selected 和 arr,监听 selected是为了随时了解商品有没有全选中,主要通过监听Length。监听arr是判断商品有没有被删除,如果arr的length改变,则表示商品有被删除,需要重新计算总金额。



    vmselected$watch("length",
    function(n)
    {
    vmcheckAllbool
    = n === vmarrsize()
    vmcal();
    });
    vmarr$watch("length",
    function(n)
    {
    vmcal();
    });

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


    lt;!DOCTYPE htmlgt; lt;htmlgt;
    lt;headgt;
    lt;titlegt;购物车lt;/titlegt;
    lt;meta http-equiv="Content-Type"
    content="text/html; charset=UTF-8"gt;
    lt;meta http-equiv="X-UA-**patible"
    content="IE=edge" /gt;
    lt;script src="/avalonjs"
    gt;lt;/scriptgt;
    lt;scriptgt;
      var
    vm = avalondefine({
      $id:
    "test",
      arr
    : [
       {
       id:1,
       num:1,
       price:455,
       text:'商品1'
       },
       {
       id:2,
       num:1,
       price:88,
       text:'商品2'
       }
      ],
      selected
    : ["1"],
      checkAllbool
    : false,
      checkAll
    : function() {
       if
    (thischecked) {
       var
    _arr = [];
       avaloneach(vmarr,function(index,item){
        _arr[index]
    = itemid+'';
       });
       vmselected
    = _arr;
       }
    else {
       vmselected=[];
       }
      },
      plus:
    function(el){
       elnum++;
       vmcal();
      },
      minus:
    function(el){
       if(elnumgt;1){
       elnum--;
       vmcal();
       }
      },
      del:
    function(el){
       vmarrremove(el);
      },
      changeNum:
    function(el){
       var
    _value = thisvalue,
       _reg
    = /^[1-9]\d63;$/
       ;
       if(!_regtest(_value)){
       thisvalue
    = 1;
       elnum
    = 1;
       }else{
       elnum
    = _value;
       }
       vmcal();
      },
      total:0,
      cal:
    function(){
       var
    _arr = thisarr,
       _selected
    = thisselected,
       i
    = 0,
       _obj
    = '',
       _prcie
    = 0
       ;
       if(_selectedlength){
       for(;ilt;_selectedlength;i++){
        _obj
    = thisfindById(_selected[i]) ||{};
        if(_objprice
      _objnum){
        _prcie
    = _prcie + _objprice * _objnum;
        }
       }
       }
       thistotal
    = _prcie;
       },
      findById:
    function(id){
       if(!id)
    return '';
       var
    i=0,
       _arr
    = thisarr,
       _obj
    = '',
       _id
    = parseInt(id,10)
       ;
       for(;ilt;_arrlength;i++){
       if(_arr[i]id
    === _id){
        _obj
    = _arr[i];
       }
       }
       return
    _obj;
      }
      });
      vmselected$watch("length",
    function(n) {
      vmcheckAllbool
    = n === vmarrsize()
      vmcal();
      });
      vmarr$watch("length",
    function(n) {
      vmcal();
      });
      vmcal();
    lt;/scriptgt;
    lt;/headgt;
    lt;body ms-controller="test"gt;
    lt;ul ms-visible="arrlength"gt;
      lt;ligt;lt;input type="checkbox"
    ms-click="checkAll" ms-duplex-checked="checkAllbool"/gt;全选lt;/ligt;
      lt;li ms-repeat="arr"
    gt;
      lt;input type="checkbox"
    ms-attr-value="elid" ms-duplex="selected" /gt;
      {{eltext}}
      lt;input type="text"
    name="" ms-attr-value="elnum" ms-on-input="changeNum(el)"gt;
      lt;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)"gt;加lt;/agt;
      lt;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)"gt;减lt;/agt;
      lt;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)"gt;删除lt;/agt;
      lt;pgt;单价:{{elprice
    | currency}}lt;/pgt;
      lt;pgt;金额:{{elnum*elprice
    | currency}}lt;/pgt;
      lt;/ligt;
    lt;/ulgt;
    lt;pgt;总金额:{{total
    | currency}}lt;/pgt;
    lt;/bodygt;
    lt;/htmlgt;

    用avalon时间还不久,一步步来,希望能更深入了解mvvm框架,在后面的日子里应用更多的场景。
    以上所述是小编给大家介绍的Avalonjs 实现简单购物车功能(实例代码),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。
    您需要登录后才可以回帖 登录 | 立即注册

    关闭

    蚂蚁站长论坛推荐上一条 /1 下一条

    QQ|Archiver|手机版|广告服务|蚂蚁站长-站长之家 ( 黔ICP备16008478号-1  

    GMT+8, 2017-10-19 07:42

    Powered by 站长论坛

    © 2007-2013 Jzant.com Inc.

    回顶部