【问题标题】:Knockout checkbox selection filter剔除复选框选择过滤器
【发布时间】:2013-06-19 10:02:39
【问题描述】:

我是 knockoutjc 图书馆的新手,您能帮帮我吗?我已经像这样在 javascript 中创建了一个新模型。

代码在这里:

        <h2>Category : Throusers</h2>

    <h3>Sizes</h3>
    <ul data-bind="foreach: products">
        <li>
            <input type="checkbox" data-bind="value: size.id" />
            <label data-bind="text: size.name"></label>
        </li>
    </ul>

    <h3>Colors</h3>
    <ul data-bind="foreach: products">
        <li>
            <input type="checkbox" data-bind="value: color.id" />
            <label data-bind="    text: color.name"></label>
        </li>
    </ul>

    <h3>Products</h3>
    <ul data-bind="foreach: products">
        <li>
            <label data-bind="text: name"></label> - 
            <label data-bind="text: size.name"></label>-
            <label data-bind="text: color.name"></label>
        </li>
    </ul>

    <script type="text/javascript">

        function Color(id, name) {
            return {
                id: ko.observable(id),
                name: ko.observable(name)
            };
        };

        function Size(id, name) {
            return {
                id: ko.observable(id),
                name: ko.observable(name)
            };
        }

        function Product(id,name, size, color) {
            return {
                id: ko.observable(),
                name: ko.observable(name),
                size: size,
                color: color
            };
        };

        var CategoryViewModel = {
            id: ko.observable(1),
            name: ko.observable("Throusers"),
            products: ko.observableArray([
                new Product(1,"Levi's 501", new Size(1, "30-32"), new Color(1, "Red")),
                new Product(2,"Colins 308", new Size(2, "32-34"), new Color(2, "Black")),
                new Product(3,"Levi's 507", new Size(1, "30-32"), new Color(3, "Blue"))
            ])
        };

        ko.applyBindings(CategoryViewModel);
    </script>

现在,

  1. 我想要这个:重复的尺寸和颜色不应该列出。
  2. 当我从颜色中选择颜色时,应列出所选颜色的产品,而应禁用其他产品

如果模型错误?

【问题讨论】:

    标签: javascript jquery knockout.js viewmodel


    【解决方案1】:

    我已尝试解决您的问题。 我从头开始写一切,看看。可能有一些错误,没有时间进行大量测试。但您现在可以轻松添加所需的任何自定义过滤器。

    http://jsfiddle.net/blackjim/8y5PP/12/

        //    jQuery 1.10 loaded
    
    var myAPP = (function($,ko){
    
        // trouserModel constructor
        var TrouserModel = function(id,name,color,size,visible){
            // maybe better if fields are ko observable, depends on other details
            this.id = id||0,
            this.name = name||'',
            this.color = color||'',
            this.size = size||'',
            this.visible = visible||true;
    
            return ko.observable(this);
        }
    
        // main viewmodel
        var trouserProducts = {
            data: ko.observableArray(),
            filters: ko.observableArray()
        }
    
        trouserProducts.sizeFilter = ko.computed(setFilter('size'));
        trouserProducts.colorFilter = ko.computed(setFilter('color'));
        trouserProducts.updateFilter = function(element, valueAccessor, allBindingsAccessor) {
    
            var ar = trouserProducts.data();
            if(!ar[0]) return true;
            var activeFilters = trouserProducts.filters().filter(function(el){return el().on;});
    
            for(var i=0; i<ar.length; i++){
    
                for(var j=0; j<activeFilters.length; j++){
                    var thisProp = ar[i]()[activeFilters[j]().prop].toLowerCase();
    
                    if( thisProp===activeFilters[j]().value ){
                        var that = ar[i]();
    
                        ar[i]({
                            id: that.id,
                            name: that.name,
                            color: that.color,
                            size: that.size,
                            visible: true
                        });
                        break;
                    }
                }
                if( j===activeFilters.length ){
                    var that = ar[i]();
    
                    ar[i]({
                        id: that.id,
                        name: that.name,
                        color: that.color,
                        size: that.size,
                        visible: false
                    });
                }
            }
    
            return true;
        };
    
        // helper functions
        var makeFilter = function(prop,value){
            var ar = trouserProducts.filters()
                value = value.toLowerCase();    //    normalize values (OPTIONAL)
    
            for(var i=0; i < ar.length ;i++){
                var that = ar[i]();
    
                if(that.prop===prop && that.value===value){
                    that.on = true;
                    return false;
                }
            }
    
            // add filter
            trouserProducts.filters.push(ko.observable({ 
                prop: prop,
                value: value,
                on: true,
                updateFilter: function(){
                    trouserProducts.updateFilter();
                    return true;
                }
            }));
        }
    
        // return a function with a specific filter
        function setFilter(prop){
            var prop = prop,
                propFilter = function(el,i,ar){
                    // el is ko observable filter here
                    return el().prop === prop;
                };
    
            return function(){            
                return trouserProducts.filters().filter(propFilter);
            }
        };
    
        var addTrouser = function(id,name,color,size){
            var newTrouser = new TrouserModel(id,name,color,size);
            color && makeFilter('color',color);  // make color filter
            size && makeFilter('size',size);     // make size filter
            trouserProducts.data.push(newTrouser);  // add new trouserModel
        }
    
        return {
            trouserProducts: trouserProducts,
            addTrouser: addTrouser
        }
    }(jQuery,ko));
    
    // add your initial products here
    myAPP.addTrouser(1,"Levi's 501","Red","30-32");
    myAPP.addTrouser(2,"Levi's 507","Black","32-34");
    myAPP.addTrouser(3,"Levi's 507","Black","30-32");
    myAPP.addTrouser(4,"Dirty jeans","Blue","32-34");
    myAPP.addTrouser(5,"Dirty jeans","Red","32-34");
    
    ko.applyBindings(myAPP.trouserProducts);
    
    window.myAPP = myAPP;
    

    【讨论】:

      【解决方案2】:

      您不应将尺寸和颜色存储在产品模型中,而应单独存储它们——就像标准化数据库一样。

      仅存储产品型号中可用的尺码和颜色的 ID。

      然后,颜色列表和尺寸列表的 foreach 应该遍历尺寸模型中的所有尺寸和颜色模型中的所有颜色。

      visible 绑定添加到产品列表。如果产品具有尺码 ID 和颜色 ID,则返回 true。

      最后,我可能还会将您的产品模型的尺寸和颜色属性放入数组中,这样每个产品都可以有多种颜色和尺寸与之关联。

      【讨论】:

        猜你喜欢
        • 2017-09-02
        • 2013-07-18
        • 1970-01-01
        • 1970-01-01
        • 2016-10-31
        • 1970-01-01
        • 2019-02-17
        • 1970-01-01
        • 2015-05-04
        相关资源
        最近更新 更多