最近学习了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点这里