2016-09-05 8 views
1

Я хотел бы использовать следующий ValueConverter и сделать его многоразовым для многих видов.Refactor 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"], тогда я просто хочу совместить столбец zipcode и не потребуется никакого оператора 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!

ответ

1

Вот решение, которое я придумал, как я не везло с построением логического ИЛИ заявление с Eval():

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; 
    } 
} 

вид.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"]; 
    }