【问题标题】:Refactor ValueConverter to filter dynamically重构 ValueConverter 以动态过滤
【发布时间】:2016-09-05 04:28:40
【问题描述】:

我想采用以下 ValueConverter 并使其可用于许多视图。

export class ProductFilterValueConverter {
    toView(array, value) {
        var regex = new RegExp(value, 'gi');
        var matcher = item =>
            item.abbr.match(regex) || item.name.match(regex);

        return array.filter(
            matcher
        );
    }
}

上面的过滤器从文本字段中获取一个值,并匹配我的“缩写”列或“名称”列。

重构以使其可重用的第 1 步是添加一个附加参数,该参数可能是一个字符串数组,其中包含我想包含在匹配 OR 逻辑中的列。

如果我在数组中传入一个值,例如["zip"],那么我只想匹配我的邮政编码列,并且不需要 OR 运算符。如果像上面的情况一样,我想匹配 m,y 产品,也许我的数组看起来像:["abbr","name"]

上面的这个方法或者可能定义了另一个知道所有不同对象列的对象,我们可以将其用作查找:

var lookup = {
    products: ["abbr","name"],
    zipcodes: ["zip"],
    offices: ["city", "state", "zipcode"]
}

我预见到这个ValueConverter 在我的新站点中被用作过滤器的许多内容。最好在任何对象上使用它,并将搜索项作为第二个参数传递,并将要匹配的列名列表作为第三个参数传递,并使用&& 和/或|| 有条件地搜索。哇,最后一点令人困惑。

以下是我目前对视图 html 代码和过滤器的 js 的拍摄,我正在为如何做到这一点而苦苦挣扎:

数据(我们正在过滤的实用程序对象)

[
  {
    "id": 1,
    "utilityName": "Big Valley",
    "abbr": "Big Valley",
    "city": "Big Bear Lake"
  },
  {
    "id": 2,
    "utilityName": "Pac Electric",
    "abbr": "PE",
    "city": "Los Angelas"
  }
]

GenericFilter.js

export class GenericFilterValueConverter {
    toView(array, value, cols) {

        var columns = cols;
        var matchLogic = "item => {";
        var regex = new RegExp(value, 'gi');
        //debugger;
        for (var i = 1; i <= columns.length; i++) {
            matchLogic += "item." + columns[i] + ".match(regex)";
            matchLogic += (i < columns.length) ? " || " : "";
            matchLogic += (i === columns.length ? "}" : "");
        }
        var matcher = eval(matchLogic);

        return array.filter(
            matcher
        );
    }
}

view.js

export class Utilities { 
    constructor(...) {
    //below the definedColumns are defined in the js module
    this.definedColumns = ["abbr","utilityName"];
}

view.html

<template>
    <!--<require from="./officeFilter"></require>-->
    <require from="../services/genericFilter"></require>
    <input type="text" name="searchValue" value.bind="searchValue" />
    <div class="grid" repeat.for="office of offices | genericFilter:searchValue:definedColumns">
            <!--MORE HTML HERE TO RENDER GRID-->
        </div>
    </div>
</template>

目前我没有收到 JavaScript 错误,但我的过滤器也不再工作。我的页面上的结果为零,好像 ValueConverter 第一次运行一样,array.filter 可能过滤掉了所有结果?

使用eval的想法显然不是最伟大的,我在下面得出的答案并没有使用邪恶的eval!

【问题讨论】:

    标签: javascript aurelia valueconverter es6-module-loader


    【解决方案1】:

    这是我想出的解决方案,因为我没有运气使用 eval() 构建逻辑 OR 语句:

    GenericFilter.js

        export class GenericFilterValueConverter {
    
        toView(array, value, cols, showResults=false) {
    
            if (!value) {
                return showResults ?  array :  [];
            };
    
            var filteredArray = array.filter(
                function(objArray) {
                    for (var col in objArray) {
                        if (objArray.hasOwnProperty(col)) {
                            if (cols.indexOf(col) != -1 && objArray[col].toLowerCase().indexOf(value.toLowerCase()) != -1) {
                                return true;
                            }
                        }
                    };
                    return false;
                });
            return filteredArray;
        }
    }
    

    view.html

    <template>
        <require from="../services/genericFilter"></require>
        <input type="text" name="searchValue" value.bind="searchValue"/>
            <div  class="grid" repeat.for="utility of utilities | genericFilter:searchValue:definedColumns:true">
                    <!--template repeats for each utility-->
                </div>
            </div>
        </div>
    </template>
    

    view.js

     export class Utilities {
        constructor(utilityNameData, router) {
            this.data = utilityNameData;
            this.router = router;
            this.utilities = [];
    
            //...
            this.definedColumns = ["abbr","utilityName"];
        }
    

    【讨论】:

      猜你喜欢
      • 2017-09-20
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 2015-08-29
      • 1970-01-01
      • 1970-01-01
      • 2012-02-17
      • 2016-11-25
      相关资源
      最近更新 更多