• 使用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,下载回来运行

  • 相关阅读:
    javascript的严格模式:use strict
    Ionic在线打包IOS平台应用
    安装nodejs6.9x以后,原来在nodejs4.2.x中运行正常的ionic项目出现问题的解决
    cordova插件分类
    ionic 启用sass
    ngCordova
    为Asp.net WebApi 添加跨域支持
    使用ionic framework创建一个简单的APP
    研究主题
    近两天让我羞愧难当的遭遇
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/3422004.html
Copyright © 2020-2023  润新知