programing tip

AngularJS의 여러 특정 모델 속성으로 필터링 (OR 관계)

itbloger 2020. 8. 11. 08:02
반응형

AngularJS의 여러 특정 모델 속성으로 필터링 (OR 관계)


http://docs.angularjs.org/api/ng.filter:filter 에서 예제를 살펴보십시오.

을 사용하여 모든 전화 속성으로 <input ng-model="search">검색 할 수 있으며을 사용하여 이름으로 만 검색 할 수 <input ng-model="search.name">있으며 결과는 이름별로 적절하게 필터링됩니다 (전화 번호를 입력해도 예상대로 결과가 반환되지 않음).

하자 내가, 내가 어떻게에 의해 필터링에 대해 갈 것 "이름"속성,에 "전화"속성, 그리고 "비밀"속성을 가진 모델이 있다고 모두 "전화"속성과 "이름"을 하지 은 "비밀"속성을 ? 따라서 본질적으로 사용자는 이름이나 전화 번호를 입력 할 수 ng-repeat있으며은 올바르게 필터링되지만 사용자가 "비밀"값의 일부와 동일한 값을 입력하더라도 아무것도 반환하지 않습니다.

감사.


여기 플런 커가 있습니다

더 깔끔한 코드와 쿼리 및 검색 목록 항목 모두 대소 문자를 구분하지 않는 새로운 플 런커

주요 아이디어는 이러한 목적을 달성하기 위해 필터 기능을 만드는 것입니다.

에서 공식 문서

function : 술어 함수를 사용하여 임의의 필터를 작성할 수 있습니다. 이 함수는 배열의 각 요소에 대해 호출됩니다. 최종 결과는 술어가 true를 리턴 한 요소의 배열입니다.

<input ng-model="query">

<tr ng-repeat="smartphone in smartphones | filter: search "> 

$scope.search = function(item) {
    if (!$scope.query || (item.brand.toLowerCase().indexOf($scope.query) != -1) || (item.model.toLowerCase().indexOf($scope.query.toLowerCase()) != -1) ){
        return true;
    }
    return false;
};

최신 정보

어떤 사람들은 실제 성능에 대한 우려를 가질 수 있습니다.

현실 세계에서 우리는 아마도 컨트롤러에서 이런 종류의 필터를 할 것입니다.

수행 방법을 보여주는 세부 게시물 은 다음과 같습니다 .

간단히 말해, ng-change새로운 검색 변경을 모니터링하기위한 입력에 추가 합니다.

그런 다음 필터 기능을 트리거합니다.


API 참조에 설명 된대로 객체를 매개 변수로 필터 표현식에 전달할 수 있습니다 . 이 개체는 다음과 같이 관심있는 속성을 선택적으로 적용 할 수 있습니다.

<input ng-model="search.name">
<input ng-model="search.phone">
<input ng-model="search.secret">
<tr ng-repeat="user in users | filter:{name: search.name, phone: search.phone}">

여기 플런 커가 있습니다

주의 ...이 예제는 AngularJS 1.1.5에서 잘 작동하지만 항상 1.0.7에서는 잘 작동하지 않습니다. 이 예에서 1.0.7은 모든 것이 필터링 된 상태로 초기화 된 다음 입력 사용을 시작할 때 작동합니다. 공백으로 시작하더라도 입력에 일치하지 않는 값이있는 것처럼 동작합니다. 안정적인 릴리스를 유지하려면 상황에 맞게 시도해보십시오. 그러나 일부 시나리오에서는 1.2.0이 릴리스 될 때까지 @maxisam의 솔루션을 사용할 수 있습니다.


나는 @maxisam의 대답에서 영감을 얻었고 나만의 정렬 기능을 만들었고 그것을 공유하고 싶지만 (지루하기 때문에).

상황은 나는 자동차의 배열을 필터합니다. 필터링 할 선택된 속성은 이름, 연도, 가격 및 km입니다. 부동산 가격과 km는 숫자입니다 (따라서 사용 .toString). 또한 대문자를 제어하고 싶습니다 (따라서 .toLowerCase). 또한 필터 쿼리를 다른 단어로 나눌 수 있기를 원합니다 (예 : 필터 2006 Acura가 주어지면 2006 년과 이름이 일치하는 Acura를 찾습니다).

필터에 전달하는 함수

        var attrs = [car.name.toLowerCase(), car.year, car.price.toString(), car.km.toString()],
            filters = $scope.tableOpts.filter.toLowerCase().split(' '),
            isStringInArray = function (string, array){
                for (var j=0;j<array.length;j++){
                    if (array[j].indexOf(string)!==-1){return true;}
                }
                return false;
            };

        for (var i=0;i<filters.length;i++){
            if (!isStringInArray(filters[i], attrs)){return false;}
        }
        return true;
    };

타사 라이브러리를 사용할 수있는 경우 멋진 필터 모음이있는 'Angular Filters'가 유용 할 수 있습니다.

https://github.com/a8m/angular-filter#filterby

collection | filterBy: [prop, nested.prop, etc..]: search

이 답변이 도움이되기를 바랍니다. 다중 값 필터

바이올린의 작업 예

arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}

여기에는 좋은 해결책이 많이 있지만 이것으로 다른 길을가는 것이 좋습니다. 검색이 가장 중요하고 '비밀'속성이 뷰에서 전혀 사용되지 않는 경우; 이에 대한 나의 접근 방식은 모든 이점과 함께 내장 각도 필터를 사용하고 단순히 모델을 새로운 객체 배열에 매핑하는 것입니다.

질문의 예 :

$scope.people = members.map(function(member) { 
                              return { 
                                name: member.name, 
                                phone: member.phone
                              }});

이제 html에서는 일반 필터를 사용하여 이러한 속성을 모두 검색합니다.

<div ng-repeat="member in people | filter: searchString">

angularJs에서 filterBy를 사용하는 매우 간단한 접근 방식

작업 plnkr의 경우이 링크를 따르십시오

http://plnkr.co/edit/US6xE4h0gD5CEYV0aMDf?p=preview

이것은 특별히 단일 속성을 사용하여 여러 열을 검색하지만 전부는 아닙니다.

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script data-require="angular.js@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js"></script>
    <script data-require="angular-filter@0.5.2" data-semver="0.5.2" src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.2/angular-filter.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="myCtrl as vm">
  <input type="text" placeholder="enter your search text" ng-model="vm.searchText" />
   <table>
     <tr ng-repeat="row in vm.tableData | filterBy: ['col1','col2']: vm.searchText">
       <td>{{row.col1}}</td>
       <td>{{row.col2}}</td>
       <td>{{row.col3}}</td>
     </tr>
   </table>
   <p>This will show filter from <b>two columns</b> only(col1 and col2) . Not from all. Whatever columns you add into filter array they
   will be searched. all columns will be used by default if you use <b>filter: vm.searchText</b></p>
  </body>
</html>

제어 장치

// Code goes here
(function(){

  var myApp = angular.module('myApp',['angular.filter']);

  myApp.controller('myCtrl', function($scope){
    var vm= this;
    vm.x = 20;

    vm.tableData = [
      {
        col1: 'Ashok',
        col2: 'Tewatia',
        col3: '12'
      },{
        col1: 'Babita',
        col2: 'Malik',
        col3: '34'
      },{
        col1: 'Dinesh',
        col2: 'Tewatia',
        col3: '56'
      },{
        col1: 'Sabita',
        col2: 'Malik',
        col3: '78'
      }
      ];
  })

})();

http://plnkr.co/edit/A2IG03FLYnEYMpZ5RxEm?p=preview

Here is a case sensitive search that also separates your search into words to search in each model as well. Only when it finds a space will it try to split the query into an array and then search each word.

It returns true if every word is at least in one of the models.

$scope.songSearch = function (row) {
    var query = angular.lowercase($scope.query);
    if (query.indexOf(" ") > 0) {
        query_array = query.split(" ");
        search_result = false;
        for (x in query_array) {
            query = query_array[x];
            if (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1){
                search_result = true;
            } else {
                search_result = false;
                break;
            }
        }
        return search_result;
    } else {
        return (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1);
    }
};

I like to keep is simple when possible. I needed to group by International, filter on all the columns, display the count for each group and hide the group if no items existed.

Plus I did not want to add a custom filter just for something simple like this.

        <tbody>
            <tr ng-show="fusa.length > 0"><td colspan="8"><h3>USA ({{fusa.length}})</h3></td></tr>
            <tr ng-repeat="t in fusa = (usa = (vm.assignmentLookups | filter: {isInternational: false}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>
        <tbody>
            <tr ng-show="fint.length > 0"><td colspan="8"><h3>International ({{fint.length}})</h3></td></tr>
            <tr ng-repeat="t in fint = (int = (vm.assignmentLookups | filter: {isInternational: true}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>

Filter can be a JavaScript object with fields and you can have expression as:

ng-repeat= 'item in list | filter :{property:value}'

Here's simple solution for those who want a quick filter against an object:

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face'}">{{card.Name}}</option>
</select>

The array filter lets you mimic the object you are trying to filter. In the above case, the following classes would work just fine:

var card = function(name, type) {
  var _name = name;
  var _type = type;

  return {
    Name: _name,
    Type: _type
  };
};

And where the deck might look like:

var deck = function() {
  var _cards = [new card('Jack', 'Face'),
                new card('7', 'Numeral')];

  return {
    Cards: _cards
  };
};

And if you want to filter multiple properties of the object just separate field names by a comma:

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face', Name: 'Jack'}">{{card.Name}}</option>
</select>

EDIT: Here's a working plnkr that provides an example of single and multiple property filters:

http://embed.plnkr.co/i0wCx6l1WPYljk57SXzV/


I might be very late but this is what I ended up doing. I made a very general filter.

angular.module('app.filters').filter('fieldFilter', function() {
        return function(input, clause, fields) {
            var out = [];
            if (clause && clause.query && clause.query.length > 0) {
                clause.query = String(clause.query).toLowerCase();
                angular.forEach(input, function(cp) {
                    for (var i = 0; i < fields.length; i++) {
                        var haystack = String(cp[fields[i]]).toLowerCase();
                        if (haystack.indexOf(clause.query) > -1) {
                            out.push(cp);
                            break;
                        }
                    }
                })
            } else {
                angular.forEach(input, function(cp) {
                    out.push(cp);
                })
            }
            return out;
        }

    })

Then use it like this

<tr ng-repeat-start="dvs in devices |  fieldFilter:search:['name','device_id']"></tr>

Your search box be like

<input ng-model="search.query" class="form-control material-text-input" type="text">

where name and device_id are properties in dvs


I solved this simply:

<div ng-repeat="Object in List | filter: (FilterObj.FilterProperty1 ? {'ObjectProperty1': FilterObj.FilterProperty1} : '') | filter:(FilterObj.FilterProperty2 ? {'ObjectProperty2': FilterObj.FilterProperty2} : '')">

참고URL : https://stackoverflow.com/questions/13216115/filtering-by-multiple-specific-model-properties-in-angularjs-in-or-relationship

반응형