最近學習了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點這裏