Ruby's Louvre

每天学习一点点算法

导航

< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8

统计

使用avalon实现SKU组合查询功能

SKU(stock keeping unit库存量单位)组合查询是网上商场一个非常常用的功能。具体来说,一件商品会有许多型号,许多颜色,许多产地,许多码寸,而满足用户选中的这些条件的具体商品可能有库存,也可能没有。我们把型号,颜色,产地,码寸什么的都分成一栏,每一栏的选项都有三种形态,可选,不可选,已选中。选中某一栏的一个选项的话,会影响到另外一些栏的项目的选中状态。如下图:

网上也有文章介绍它们的实现,涉及大量复杂的算法,HTML都是用JS动态生成的,非常不直观。并且那个东西这么简单,还要用那么复杂的算法啊,脑子被狗吃了。

在avalon中,由于VM对象是一个状态机,对这种联动功能有着天然的优势。我们只要把数据列出来,剩下的事就交给avalon好了。

下面是模板,它是由GITHUB的一个例子改过来的。一共五栏,换言之,VM有五个数组。然后里面每顶通过ms-class处理它们的状态。选择是通过点击事件实现,因此有ms-click。每个项目是否选中,通过涨是否等于某一个值判定,因此我搞了versionsChecked,colorsChecked,comboChecked等变量。

<div ms-controller="sku" id="sku">
           <div>
               版本:
               <span ms-each-el="versions">
                   <span class="cell" ms-click="select(el, 'versions')"  ms-class-disabled='el.disabled' ms-class-checked='versionsChecked == el.value'>{{el.text}}</span>
               </span>
           </div>
           <div>
               机身颜色:
               <span ms-each-el="colors">
                   <span class="cell" ms-click="select(el, 'colors')" ms-class-disabled='el.disabled' ms-class-checked='colorsChecked == el.value'>{{el.text}}</span>
               </span>
           </div>
           <div>
               手机套餐:
               <span ms-each-el="combo">
                   <span class="cell"  ms-click="select(el, 'combo')" ms-class-disabled='el.disabled'  ms-class-checked='comboChecked == el.value'>{{el.text}}</span>
               </span>
           </div>
           <div>
               机身内存:
               <span ms-each-el="memory">
                   <span class="cell" ms-click="select(el, 'memory')" ms-class-disabled='el.disabled' ms-class-checked='memoryChecked == el.value'>{{el.text}}</span>
               </span>
           </div>
       </div>
sku最麻烦之处在于,点击了某一栏的项目会影响到其他栏的项目,这种逻辑我抽象成一个command命令,以columnName:item1,item2...;columnName2:item3,item4...;保存。

具体如下:

var model = avalon.define("sku", function(vm) {
vm.select = function(el, name) {
        if (el.disabled)
            return
        var command = el.command
        model[name + "Checked"] = el.value
        command.split(";").forEach(function(str) {
            var arr = str.split(":")
            var check = arr[1]
            var array = model[arr[0]] || []
            array.forEach(function(elem) {
                elem.disabled = !!(check && check.indexOf(elem.value) !== -1)
            })
        })
    }
    vm.versions = [
        {value: 'cn', "text": "中国大陆", disabled: false,  command: "colors:lightgreen;"},
        {value: "hk", text: "港澳台", checked: false,  command: "colors:lightyellow,black,blue,gray,yellow,white"},
        {value: "eu", text: "欧洲", checked: false,  command: "colors:lightyellow,blue,gray,yellow,red,lightgreen"}
    ]
    vm.versionsChecked = ""
    
   
    vm.colors = [
        {value: 'lightyellow', "text": "浅黄色", disabled: false, command: "versions:hk,eu"},
        {value: "black", text: "黑色", disabled: false, command: "versions:hk"},
        {value: "blue", text: "蓝色", disabled: false, command: "versions:hk,eu"},
        {value: "gray", text: "浅灰色", disabled: false, command: "versions:hk,eu"},
        {value: "yellow", text: "黄色", disabled: false, command: "versions:hk,eu"},
        {value: "white", text: "白色", disabled: false, command: "versions:hk"},
        {value: "lightgreen", text: "浅绿色", disabled: false, command: "versions:cn,eu;combo:set2,set3"},
        {value: "red", text: "红色", disabled: false, command: "versions:eu"}
 
    ]
    vm.colorsChecked = ""
    
    vm.combo = [
        {value: 'standard', "text": "官方标配", disabled: false,command: ""},
        {value: "set2", text: "套餐二", disabled: false,command: "colors:lightgreen"},
        {value: "set3", text: "套餐三", disabled: false,command: ""}
    ]
    vm.comboChecked = ""
    
    vm.memory = [{value: "32g", text: "32G", disabled: false,command: ""}]
    vm.memoryChecked = "32g"
})

再加一点CSS装饰一下就搞定。

#sku .cell{
    display:inline-block;
    padding:2px 5px;
    border:2px solid #ccc;
    color:#000;
    cursor:pointer;
    height: 18px;
    line-height: 18px;
}
#sku .cell.checked{
    border-color:red!important;
    color:red!important;
}
#sku .cell.disabled{
    border:2px dashed #d6d6d6;
    color:#cdcdcd;
    cursor:not-allowed;
}
#sku div{
    margin-top:10px;
}

大家可以到我的GITHUB,下载回来运行

如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码

posted on   司徒正美  阅读(4165)  评论(3编辑  收藏  举报

点击右上角即可分享
微信分享提示