最近学习了angular,正好又完整的作了一个电商网站,就利用angular实现了一个sku组合查询组件,首先介绍sku是个什么东西。sku=stock keeping unit(库存量单位),sku即库存进出计量的单位, 能够是以件、盒、托盘等为单位。在服装、鞋类商品中使用最多最广泛。 例如服装中一个SKU(XL###红色###男款的一件衣服)一般表示:尺码、颜色、款式等。html
demo(先看下例子):http://codepen.io/hzxs1990225/pen/VYyOdW前端
repository:https://github.com/amibug/angular-skujava
angular-sku组件具体实现了什么功能呢?一种商品不一样的sku组合是互斥的,例如一件衣服,可能有不少属性,属性能够自由组合,可是有的属性没有货,这时候须要实现一个功能,用户没法选择属性组合。 例如XL###红色没有货,而S###红色有货,则用户选了红色以后,XL就不能选,S能够选。S###红色选中以后,在callback中更新库存等操做。git
angular-sku它是一个util组件,样式能够由使用者本身定义。html部分是由后台模板引擎,基于模板来生成的文本输出,例如freemaker(java语言编写的模板引擎),通常是这么写的。自定义的html写在ui-sku中间angularjs
<#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以前)github
<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为组件结接收的数据(数据有必定格式,须要后台开发配合给)bootstrap
{ 'S#红色#男': { count: 0 }, 'M#红色#女': { count: 0 }, 'S#橙色#男': { count: 1 }, 'M#橙色#女': { count: 1 }, ..... }
splitStr为不一样key之间的分格缝(S#红色#男中指的是‘#’)api
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点这里