2017-01-09 2 views
0

Я делал фильтрацию много раз раньше, но у меня возникают проблемы с этим конкретным случаем. У меня есть список объектов, созданных в разбивке на страницы, но я также хочу, чтобы их можно было фильтровать для удобства использования. Пример объект может выглядеть следующим образом:Фильтр AngularJs на двух объектных полях

{ 
    baseline:0.75 
    clonedFrom:Object 
    description:"Just a simple description.." 
    includeable:false 
    key:"bc889881-7979-4e04-b586-d53faab26b6b" 
    name:"Just a simple question?" 
    type:"BayesianModel" 
    version:1483477351992 
    versionComment:null 
    versionLabel:"0.11" 
} 

По большей части, что объект выглядит как произвольно, я просто включил его для простоты ответить. Я пытаюсь одновременно фильтровать как name, так и description. Например, если пользователь знал ключевое слово, либо они могли сузить результаты.

У меня есть input для фильтра и результаты внутри <ul>, как показано ниже:

<ul class="list-group"> 
    <li class="list-group-item"> 
    <div class="form-group has-feedback"> 
     <input type="text" 
      ng-model="vm.resultFilter" 
      ng-change="vm.updateFilter()" 
      class="form-control filterInput" 
      placeholder="Filter Results" /> 
     <span ng-if="vm.resultFilter" 
      ng-click="vm.resultFilter = ''; vm.updateFilter();" 
      class="fa fa-times fa-lg form-control-feedback"> 
     </span> 
    </div> 
    </li> 
    <li class="list-group-item link-row model-list" 
     ng-repeat="result in vm.filteredResults 
      | startFrom : ((vm.currentPage - 1) * vm.itemsPerPage) 
      | limitTo: vm.itemsPerPage" 
     ng-if="result.name != vm.model.name" 
     ng-click="vm.selected = result;" 
     ng-class="{selected: result === vm.selected}" 
     ng-init="displayNumber = vm.incrementDisplayIndex();"> 
    <h4 class="list-group-item-heading">{{result.description}} - {{result.name !== vm.model.name}}</h4> 
    <p class="list-group-item-text"> 
     {{result.name}} 
    </p> 
    </li> 
</ul> 

Таким образом, название фильтра vm.resultFilter и метод cooresponding, который вызывается каждый раз, когда фильтр обновлена updateFilter() (что необходимо для разбиения на страницы).

function updateFilter() { 
    vm.filteredResults = $filter('filter')(vm.results, { 
    'name': vm.resultFilter, 
    'description': vm.resultFilter 
    }); 
    vm.totalItems = vm.filteredResults.length; 
    vm.noOfPages = Math.ceil(vm.filteredResults.length/vm.itemsPerPage); 
} 

У меня возникли проблемы с тем, чтобы фильтрация работала на 100%. Иногда кажется, что это только фильтрация в поле описания, но иногда я буду искать слово, которое находится в поле описания только одного результата, и оно будет фильтроваться без результатов (что было бы ложным). Любые советы оценены.

+0

Примите во внимание, что фильтр работает с и и оператором. Это означает, что результат должен совпадать с именем и описанием условий как результата. –

+0

Я понимаю, что вы имеете в виду, но я не использую оператор 'AND' в любом месте? Если, указывая оба поля на 'vm.resultFilter', это то, что происходит. Если это так, то как я могу сделать это оператором 'OR'? – erp

+0

Указывая оба поля, фильтр работает в соответствии с условием И. Это может быть полезно http://stackoverflow.com/questions/15868248/how-to-filter-multiple-values-or-operation-in-angularjs –

ответ

1

Поскольку вы не используете filter в своем HTML, я рекомендую вам использовать свойство filter из прототипа Array.

function updateFilter() { 
    vm.filteredResults = vm.results.filter(function(item){ 
    return (item.name==vm.resultFilter || item.description==vm.resultFilter) 
    } 

    vm.totalItems = vm.filteredResults.length; 
    vm.noOfPages = Math.ceil(vm.filteredResults.length/vm.itemsPerPage); 
} 

В случае, если вам необходимо определить, содержит ли строка символы указанной строки. Вы, возможно, потребуется использовать includes вместо ==

vm.filteredResults = vm.results.filter(function(item){ 
    return (item.name.includes(vm.resultFilter) || item.description.includes(vm.resultFilter)) 
} 
+0

Отлично. Так что второй - это то, что я ищу. Просто любопытный вопрос, если вы знаете, что у вас на голове: знаете ли вы, как сделать фильтрацию в этом случае не чувствительной к регистру? Угловая по умолчанию, хотя в этом случае, так как она «включает строку», очевидно, что она будет чувствительной к регистру (что для меня нежелательно). – erp

+0

преобразует обе строки в нижний регистр со свойством String .toLowerCase() item.name.toLowerCase() включает в себя (vm.resultFilter.toLowerCase()) –

+0

ОК, круто, да, это было очевидное решение;), но просто посмотрел, есть ли у меня другие варианты. спасибо за помощь сегодня m8 – erp

Смежные вопросы