最近学习了angular,正好又完整的做了一个电商网站,就利用angular实现了一个sku组合查询组件,首先介绍sku是个什么东西。sku=stock keeping unit(库存量单位),sku即库存进出计量的单位, 可以是以件、盒、托盘等为单位。在服装、鞋类商品中使用最多最普遍。 例如服装中一个SKU(XL###红色###男款的一件衣服)通常表示:尺码、颜色、款式等。

例子

demo(先看下例子):http://codepen.io/hzxs1990225/pen/VYyOdW

repository:https://github.com/amibug/angular-sku

angular-sku组件具体实现了什么功能呢?一种商品不同的sku组合是互斥的,例如一件衣服,可能有很多属性,属性可以自由组合,但是有的属性没有货,这时候需要实现一个功能,用户无法选择属性组合。 例如XL###红色没有货,而S###红色有货,则用户选了红色之后,XL就不能选,S可以选。S###红色选中之后,在callback中更新库存等操作。

angular-sku它是一个util组件,样式可以由使用者自己定义。html部分是由后台模板引擎,基于模板来生成的文本输出,例如freemaker(java语言编写的模板引擎),一般是这么写的。自定义的html写在ui-sku中间

<#if (product.parameters?size>0)>
  <div ui-sku split-str="#" init-sku="M#红色#男" sku-data="skuInfo" on-ok="callback($event)">
  <#list product.parameters as param >
    <div class="row f-cb">
      <div class="l-col">${param.name!''}</div>
      <div class="r-col">
        <ul class="m-sku f-cb">
        <#list param.values as key >
          <li><span ng-class="{'js-seleted': keyMap['${key}'].selected, 'js-disabled': keyMap['${key}'].disabled}" ng-click="onSelect('${key}')">${key}</span></li>
        </#list>
        </ul>
      </div>
    </div>
  </#list>
  </div>
</#if>

对应生成的html(在angular代码接管之前生成的html,及angular执行bootstrap之前)

<div ui-sku split-str="#" init-sku="M#红色#男" sku-data="skuInfo" on-ok="callback($event)">
  <div class="row f-cb">
    <div class="l-col">尺码</div>
    <div class="r-col">
      <ul class="m-sku f-cb">
        <li><span ng-class="{'js-seleted': keyMap['S'].selected, 'js-disabled': keyMap['S'].disabled}" ng-click="onSelect('S')">S</span></li>
        <li><span ng-class="{'js-seleted': keyMap['M'].selected, 'js-disabled': keyMap['M'].disabled}" ng-click="onSelect('M')">M</span></li>
        ...
      </ul>
    </div>
    ...
  </div>
</div>

组件接收4个参数skuData,splitStr,initSku,onOk

  • skuData为组件结接收的数据(数据有一定格式,需要后台开发配合给)

         {
            'S#红色#男': {
              count: 0
            },
            'M#红色#女': {
              count: 0
            },
            'S#橙色#男': {
              count: 1
            },
           'M#橙色#女': {
              count: 1
            },
            .....
          }
  • splitStr为不同key之间的分格缝(S#红色#男中指的是‘#’)

  • initSku为默认设置的选中key(可以设置为M#红色#女)

  • onOk点击key之后的callback

简单讲解一下组件是怎么工作的

  • 首先手动设置transclude,解决用ng-transclude scope作用域问题

         transclude(scope, function(clone){
           element.append(clone);
        });
    
  • 根据sku-data,获得属性值的数组

        getSkuList-->transpose-->unique
        [['S', '红色,'男'], ['M','红色','女'],['S','橙色','男'],['M','橙色','女']]-->矩阵转置-->去重元素得到
        [['S', 'M'], ['红色','橙色'],['男','女']]
    
  • scope.selected保存了已选中的属性,每次点击(支持反选)属性值的时候执行checkItem,getNum会检查当前sku组合是否可以选中。getNum参考了淘宝前端的实现,已经查询过的sku组合会做缓存,是一种空间换时间的算法。

  • 设置每个属性值中数据模型中的selected和disabled

缺点

  • 所需要的数据结构格式固定

  • transclude template书写方式还是有点别扭(样式需要自定义所造成)

对angularjs的掌握程度不深,实现得不够完善,还望大牛们指出不足的地方。
最后介绍一个同事的mvvm库 regularjs,轻量级,很不错,还支持到IE6。查看reference点这里

参考

http://ued.taobao.org/blog/2012/07/sku-search-algorithm/


amibug
440 声望8 粉丝

前端菜鸟一枚