কৌণিক জেএসে কীভাবে একাধিক মান (ওআরআর) ফিল্টার করা যায়


135

আমি filterকৌণিকটি ব্যবহার করতে চাই এবং একাধিক মানের জন্য ফিল্টার করতে চাই, যদি এর কোনও একটি মান থাকে তবে তা প্রদর্শিত হবে।

আমি উদাহরণস্বরূপ এই কাঠামো আছে:

একটি বস্তু movieযা সম্পত্তি আছে genresএবং আমি এর জন্য ফিল্টার করতে চান Actionএবং Comedy

আমি জানি আমি filter:({genres: 'Action'} || {genres: 'Comedy'})কি করতে পারি তবে আমি যদি এটিকে গতিশীলভাবে ফিল্টার করতে চাই তবে কী করব। যেমনfilter: variableX

আমি কিভাবে সেট করবেন variableXমধ্যে $scopeযখন আমি ঘরানার আমি ফিল্টার আছে একটি অ্যারে আছে?

আমি এটিকে স্ট্রিং হিসাবে তৈরি করতে পারি এবং তারপরে একটি করতে পারি eval()তবে আমি ইভাল () ব্যবহার করতে চাই না ...


16
আপনি কি নিশ্চিত যে filter:({genres: 'Action'} || {genres: 'Comedy'})এমনকি কাজ করে? এটা না angular 1.3.16
twmulloy

4
1.4.8 এর জন্য একই! এটি ঠিক কাজ করে না ^^
অ্যালেক্স

উত্তর:


87

আমি কেবল একটি কাস্টম ফিল্টার তৈরি করব। তারা যে হার্ড না।

angular.module('myFilters', []).
  filter('bygenre', function() {
    return function(movies,genres) {
      var out = [];
      // Filter logic here, adding matches to the out var.
      return out;
    }
  });

টেমপ্লেট:

<h1>Movies</h1>

<div ng-init="movies = [
          {title:'Man on the Moon', genre:'action'},
          {title:'Meet the Robinsons', genre:'family'},
          {title:'Sphere', genre:'action'}
       ];" />
<input type="checkbox" ng-model="genrefilters.action" />Action
<br />
<input type="checkbox" ng-model="genrefilters.family" />Family
<br />{{genrefilters.action}}::{{genrefilters.family}}
<ul>
    <li ng-repeat="movie in movies | bygenre:genrefilters">{{movie.title}}: {{movie.genre}}</li>
</ul>

এখানে সম্পাদনা লিঙ্কটি: কৌণিক ফিল্টার তৈরি করা হয়

আপডেট : এখানে আমার মতামতটির একটি ডিমো রয়েছে এমন একটি ফ্রিডল


তাহলে আমি কি মুভি অবজেক্টগুলি প্রদর্শন করতে চাই?
জাস্টগোসচা

দুঃখিত, ফিরে আসতে আমাকে কিছুটা সময় লেগেছে। আমি আমার উত্তরটি একটি কংক্রিটের উদাহরণ সহকারে আপডেট করেছি।
পরীক্ষিত

ঠিক আছে, ধন্যবাদ, ইতিমধ্যে আমি এটি নিজেই বের করেছিলাম, তবে এটি অবশ্যই পরে কাউকে সাহায্য করবে :)
JustGoscha

হয় আমার দুটি মান যেমন সক্রিয় এবং নিষ্ক্রিয় থাকে তবে কীভাবে আমি এই ফিল্টারটি ব্যবহার করে আলাদাভাবে অনুসন্ধান করতে পারি। আমরা কাস্টম ফিল্টার করতে চাই না।
ভিজাইভি

80

আপনি ফিল্টার করতে একটি নিয়ামক ফাংশন ব্যবহার করতে পারেন।

function MoviesCtrl($scope) {

    $scope.movies = [{name:'Shrek', genre:'Comedy'},
                     {name:'Die Hard', genre:'Action'},
                     {name:'The Godfather', genre:'Drama'}];

    $scope.selectedGenres = ['Action','Drama'];

    $scope.filterByGenres = function(movie) {
        return ($scope.selectedGenres.indexOf(movie.genre) !== -1);
    };

}

এইচটিএমএল:

<div ng-controller="MoviesCtrl">
    <ul>
        <li ng-repeat="movie in movies | filter:filterByGenres">
            {{ movie.name }} {{ movie.genre }}
        </li>
    </ul>
</div>

1
উদ্বেগ পৃথককরণ ছাড়াও, কোনও কারণ (পারফরম্যান্স বুদ্ধিমান) যা এড়ানো হবে?
শান লারকিন

1
জাভাস্ক্রিপ্ট সংস্করণ যদি অন্যরা এটির সন্ধান করে:$scope.filteredMovies = $filter('filter')($scope.movies, $scope.filterByGenres);
ইভান

23

একটি কাস্টম ফিল্টার তৈরি করা এখানে ওভারকিল হতে পারে, যদি আপনার একাধিক মান থাকে তবে:

$scope.selectedGenres = "Action, Drama"; 

$scope.containsComparator = function(expected, actual){  
  return actual.indexOf(expected) > -1;
};

তারপরে ফিল্টারটিতে:

filter:{name:selectedGenres}:containsComparator

1
আমাকে অনেক সাহায্য করেছে। ধন্যবাদ
হিস্টো এনেভ

@ ক্রিসমার্ক ng-modelবর্ণিত ফিল্টারটির সাথে লিঙ্ক করতে ভিউ ফাইলটিতে কী থাকবে ? আপনার উত্তর সরলতা মত আমি ও এটা কাজ পেতে চেষ্টা কিন্তু কীভাবে করবেন নিশ্চিত নন আমার লেবেল - (দুঃখিত, এখনও এখানে শেখার) <input>'র ng-model। :)
twknab

আপনার এটি পড়তে হবে - ডকস.অঙ্গুলারজ.স.আর
আইপি

18

এখানে কাস্টম ফিল্টারটি প্রয়োগ করা হচ্ছে, যা মানগুলির অ্যারে ব্যবহার করে ডেটা ফিল্টার করবে t এটি একাধিক কী অবজেক্টকে অ্যারের এবং একক মানের উভয় সমর্থন করে support যেমনটি উল্লিখিত হিসাবে ইনঙ্গুলার জেএস এপিআই অ্যাঙ্গুলারজেএস ফিল্টার ডক একক মান সহ একাধিক কী ফিল্টার সমর্থন করে, তবে নীচে কাস্টম ফিল্টারটি কৌণিক জেএস হিসাবে একই বৈশিষ্ট্যটিকে সমর্থন করবে এবং কীগুলির অ্যারে এবং একক মানের উভয়ের সংমিশ্রণের মানকেও সমর্থন করবে lease নীচের কোড স্নিপেটটি সন্ধান করুন,

myApp.filter('filterMultiple',['$filter',function ($filter) {
return function (items, keyObj) {
    var filterObj = {
        data:items,
        filteredData:[],
        applyFilter : function(obj,key){
            var fData = [];
            if (this.filteredData.length == 0)
                this.filteredData = this.data;
            if (obj){
                var fObj = {};
                if (!angular.isArray(obj)){
                    fObj[key] = obj;
                    fData = fData.concat($filter('filter')(this.filteredData,fObj));
                } else if (angular.isArray(obj)){
                    if (obj.length > 0){
                        for (var i=0;i<obj.length;i++){
                            if (angular.isDefined(obj[i])){
                                fObj[key] = obj[i];
                                fData = fData.concat($filter('filter')(this.filteredData,fObj));    
                            }
                        }

                    }
                }
                if (fData.length > 0){
                    this.filteredData = fData;
                }
            }
        }
    };
    if (keyObj){
        angular.forEach(keyObj,function(obj,key){
            filterObj.applyFilter(obj,key);
        });
    }
    return filterObj.filteredData;
}
}]);

ব্যবহার:

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

উপরের "ফিল্টারমুটিপল" কাস্টম ফিল্টারটি বাস্তবায়নের সাথে একটি বেহাল উদাহরণ example ::: টিউমার উদাহরণ :::


1
আপনার সঠিক উদ্দেশ্য আছে বলে মনে হয় তবে আপনার উদাহরণটি প্রত্যাশার মতো কার্যকর হবে বলে মনে হয় না। টেবিলের আউটপুটটি বরং বেমানান বলে মনে হচ্ছে।
হাল্টনার

এটি নেস্টেড অবজেক্টের সাথে জেএসএন-র কাজ করে না। এটা যদি আদর্শ হত। এছাড়াও এটি length property undefinedকনসোলে একটি ত্রুটি চালায়।
সিনসাইক

এটি আমার জন্য কাজ করছে তবে এটি তালিকায় অনুসন্ধানের বৈশিষ্ট্যটি খুঁজে না পেয়ে সমস্ত ফলাফল ফিরিয়ে দেয়, এই আচরণটি উল্টাতে আমি কীভাবে করব এবং তালিকার মধ্যে মানটি না উপস্থিত থাকলে কোনও ফলাফল কীভাবে ফিরিয়ে আনতে পারি?
জাকারিয়া বেলঘিটি

@ যাকারিয়া বেলঘিটি আপনি যদি কোনও ফলাফল না চান তবে কোডটি পরিবর্তন করুন: if (fData.length > 0){ this.filteredData = fData; } কেবলমাত্র: this.filteredData = fData;
pconnor88

@ গ্রেফ্রিড আমি মনে করি যে সাইটটি আসলে স্ট্যাকওভারফ্লোকে স্ক্র্যাপ করে, তাই তারা তার উত্তর চুরি করেছিল, অন্যভাবে নয়
ক্রিস

13

আপনি যদি অ্যারে অবজেক্টে ফিল্টার করতে চান তবে দিতে পারেন

filter:({genres: 'Action', key :value }.

পৃথক সম্পত্তি সেই সম্পত্তির জন্য প্রদত্ত নির্দিষ্ট ফিল্টার দ্বারা ফিল্টার করা হবে।

তবে আপনি যদি ব্যক্তিগত সম্পত্তি দ্বারা ফিল্টার করার মতো এবং সমস্ত বৈশিষ্ট্যের জন্য বিশ্বব্যাপী ফিল্টার করতে চান তবে আপনি এর মতো কিছু করতে পারেন।

<tr ng-repeat="supp in $data | filter : filterObject |  filter : search">
যেখানে "ফিল্টারওজেক্ট" হ'ল একটি পৃথক সম্পত্তি অনুসন্ধান করার জন্য একটি বস্তু এবং "অনুসন্ধান" বিশ্বব্যাপী প্রতিটি সম্পত্তি অনুসন্ধান করবে।

~ অতুল


এটি আমার পক্ষে ভাল কাজ করেছে এবং অন্যরা ফিল্টারিংকে কোনও ফাংশনে অফলোড করার পরামর্শ দেওয়ার চেয়ে ভাল সমাধান ছিল কারণ অ্যাংুলারজেএস স্ট্রিংগুলিতে ফিল্টার করার সময় আংশিক পাঠ্য মেলে।
Snaver

9

আমি এতে কিছুটা সময় ব্যয় করেছি এবং @ ক্রিসমার্ককে ধন্যবাদ, আমি দেখেছি যে কৌণিকের ডিফল্ট filterFilterআপনাকে নিজের তুলনামূলক পাস করতে দেয়। একাধিক মানের জন্য সম্পাদিত তুলনামূলকটি এখানে:

  function hasCustomToString(obj) {
        return angular.isFunction(obj.toString) && obj.toString !== Object.prototype.toString;
  }
  var comparator = function (actual, expected) {
    if (angular.isUndefined(actual)) {
      // No substring matching against `undefined`
      return false;
    }
    if ((actual === null) || (expected === null)) {
      // No substring matching against `null`; only match against `null`
      return actual === expected;
    }
    // I edited this to check if not array
    if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
      // Should not compare primitives against objects, unless they have custom `toString` method
      return false;
    }
    // This is where magic happens
    actual = angular.lowercase('' + actual);
    if (angular.isArray(expected)) {
      var match = false;
      expected.forEach(function (e) {
        e = angular.lowercase('' + e);
        if (actual.indexOf(e) !== -1) {
          match = true;
        }
      });
      return match;
    } else {
      expected = angular.lowercase('' + expected);
      return actual.indexOf(expected) !== -1;
    }
  };

এবং যদি আমরা ডিআরওয়াইয়ের জন্য একটি কাস্টম ফিল্টার তৈরি করতে চাই:

angular.module('myApp')
    .filter('filterWithOr', function ($filter) {
      var comparator = function (actual, expected) {
        if (angular.isUndefined(actual)) {
          // No substring matching against `undefined`
          return false;
        }
        if ((actual === null) || (expected === null)) {
          // No substring matching against `null`; only match against `null`
          return actual === expected;
        }
        if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) {
          // Should not compare primitives against objects, unless they have custom `toString` method
          return false;
        }
        console.log('ACTUAL EXPECTED')
        console.log(actual)
        console.log(expected)

        actual = angular.lowercase('' + actual);
        if (angular.isArray(expected)) {
          var match = false;
          expected.forEach(function (e) {
            console.log('forEach')
            console.log(e)
            e = angular.lowercase('' + e);
            if (actual.indexOf(e) !== -1) {
              match = true;
            }
          });
          return match;
        } else {
          expected = angular.lowercase('' + expected);
          return actual.indexOf(expected) !== -1;
        }
      };
      return function (array, expression) {
        return $filter('filter')(array, expression, comparator);
      };
    });

এবং তারপরে আমরা এটি যে কোনও জায়গায় ব্যবহার করতে পারি:

$scope.list=[
  {name:'Jack Bauer'},
  {name:'Chuck Norris'},
  {name:'Superman'},
  {name:'Batman'},
  {name:'Spiderman'},
  {name:'Hulk'}
];


<ul>
  <li ng-repeat="item in list | filterWithOr:{name:['Jack','Chuck']}">
    {{item.name}}
  </li>
</ul>

অবশেষে এখানে একজন বরখাস্ত

দ্রষ্টব্য: প্রত্যাশিত অ্যারেতে কেবল স্ট্রিং , নম্বর ইত্যাদি সাধারণ জিনিস থাকতে হবে objects


ধন্যবাদ এটি আমাকে সাহায্য করেছে। একক মান ফিল্টার জন্য পরীক্ষা করতে ওথার: {নাম: 'জ্যাক' anyone কারও যদি আমার মতো প্রয়োজন হয় ...
জুয়ান

7

তোমাদের মধ্যে searchField ফিল্টার ব্যবহার করতে পারেন angular.filter

জাতীয়:

$scope.users = [
 { first_name: 'Sharon', last_name: 'Melendez' },
 { first_name: 'Edmundo', last_name: 'Hepler' },
 { first_name: 'Marsha', last_name: 'Letourneau' }
];

এইচটিএমএল:

<input ng-model="search" placeholder="search by full name"/> 
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
  {{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->

3
আপনি কৌনিক.ফিল্টার <টি এনজি-রিপিট = "সংগ্রহের মধ্যে" যেখানে "use আইডি: 1}"> {{
জেজ.নেম

1
এখানে searchথাম
আকাশ

1
আমি এটি চেষ্টা করেছি এবং আমার কৌণিক অ্যাপ্লিকেশনটিতে মডিউল এবং আমার সূচক এইচটিএমএল স্ক্রিপ্ট উভয়ই সেটআপ করেছি তবে আমি এখনও নির্দিষ্ট করে নেই কেবল সমস্ত ক্ষেত্র অনুসন্ধান করতে সক্ষম :(
২k

7

ngIfপরিস্থিতি যদি অনুমতি দেয় তবে আপনি এটি ব্যবহার করতে পারেন:

<div ng-repeat="p in [
 { name: 'Justin' }, 
 { name: 'Jimi' }, 
 { name: 'Bob' }
 ]" ng-if="['Jimi', 'Bob'].indexOf(e.name) > -1">
 {{ p.name }} is cool
</div>

1
দুর্দান্ত এবং সহজ সমাধান!
লিওপোলোডো সান্জিক 21

7

আমি যে দ্রুত সমাধান পেয়েছি তা হ'ল কৌণিক-ফিল্টারfilterBy থেকে ফিল্টারটি ব্যবহার করা , উদাহরণস্বরূপ:

<input type="text" placeholder="Search by name or genre" ng-model="ctrl.search"/>   
<ul>
  <li ng-repeat="movie in ctrl.movies | filterBy: ['name', 'genre']: ctrl.search">
    {{movie.name}} ({{movie.genre}}) - {{movie.rating}}
  </li>
</ul>

বিপরীত দিকটি হল যে কৌণিক-ফিল্টারটি মোটামুটি জনপ্রিয় একটি গ্রন্থাগার (গিটহাবের ~ 2.6k তারা) যা এখনও সক্রিয়ভাবে বিকাশিত এবং বজায় রয়েছে, তাই এটি আপনার প্রকল্পের উপর নির্ভরতা হিসাবে যুক্ত করা ভাল fine


1
এখন পর্যন্ত সেরা উত্তর। ধন্যবাদ।
ড্যানিয়েল গ্রাসজেকেক

4

আমি বিশ্বাস করি এটিই আপনি খুঁজছেন:

<div>{{ (collection | fitler1:args) + (collection | filter2:args) }}</div>

1
এটি কেবল অ্যারেগুলিকে একত্রিত করে এবং কোনও ইউনিয়ন ফিরিয়ে দেয় না।
মুয়াজ

আমি বাস্তবায়নের ভুল বোঝে না হলে আমি কীভাবে এটি সমস্যা তা দেখতে ব্যর্থ।
jKlaus

2

এটি চেষ্টা করুন

var m = angular.module('yourModuleName');
m.filter('advancefilter', ['$filter', function($filter){
    return function(data, text){
        var textArr = text.split(' ');
        angular.forEach(textArr, function(test){
            if(test){
                  data = $filter('filter')(data, test);
            }
        });
        return data;
    }
}]);

2

ধরে নেওয়া যাক আপনার দুটি অ্যারে রয়েছে, একটি সিনেমার জন্য এবং একটি জেনারের জন্য

কেবলমাত্র ফিল্টারটি ব্যবহার করুন: filter:{genres: genres.type}

এখানে জেনারগুলির অ্যারে এবং প্রকারের ধরণের জেনারের মান রয়েছে


1

আমি এটি স্ট্রিং এবং কার্যকারিতার জন্য লিখেছি (আমি জানি এটি প্রশ্ন নয় তবে আমি এটি অনুসন্ধান করে এখানে এসেছি), সম্ভবত এটি প্রসারিত হতে পারে।

String.prototype.contains = function(str) {
  return this.indexOf(str) != -1;
};

String.prototype.containsAll = function(strArray) {
  for (var i = 0; i < strArray.length; i++) {
    if (!this.contains(strArray[i])) {
      return false;
    }
  }
  return true;
}

app.filter('filterMultiple', function() {
  return function(items, filterDict) {
    return items.filter(function(item) {
      for (filterKey in filterDict) {
        if (filterDict[filterKey] instanceof Array) {
          if (!item[filterKey].containsAll(filterDict[filterKey])) {
            return false;
          }
        } else {
          if (!item[filterKey].contains(filterDict[filterKey])) {
            return false;
          }
        }
      }
      return true;
    });  
  };
});

ব্যবহার:

<li ng-repeat="x in array | filterMultiple:{key1: value1, key2:[value21, value22]}">{{x.name}}</li>


1

আমারও একই অবস্থা ছিল। কাস্টম ফিল্টার লেখা আমার পক্ষে কাজ করেছিল। আশাকরি এটা সাহায্য করবে!

জাতীয়:

App.filter('searchMovies', function() {
    return function (items, letter) {
        var resulsts = [];
        var itemMatch = new RegExp(letter, 'i');
        for (var i = 0; i < items.length; i++) {
            var item = items[i];
            if ( itemMatch.test(item.name) || itemMatch.test(item.genre)) {
                results.push(item);
            }
        }
        return results;
    };
});

এইচটিএমএল:

<div ng-controller="MoviesCtrl">
    <ul>
        <li ng-repeat="movie in movies | searchMovies:filterByGenres">
            {{ movie.name }} {{ movie.genre }}
        </li>
    </ul>
</div>

1

এখানে আমার উদাহরণটি কীভাবে টেবিল জিসফিডেলের জন্য ফিল্টার এবং নির্দেশনা তৈরি করে

নির্দেশাবলী পান তালিকা (ডেটা) এবং ফিল্টারগুলি সহ টেবিল তৈরি করুন

<div ng-app="autoDrops" ng-controller="HomeController">
<div class="row">
    <div class="col-md-12">
        <h1>{{title}}</h1>
        <ng-Multiselect array-List="datas"></ng-Multiselect>
    </div>
</div>
</div>

আমি আপনাকে সাহায্য যদি আমার আনন্দ


1

দলে যোগ দিতে খুব দেরি হলেও এটি কারওর পক্ষে সহায়তা করতে পারে:

আমরা এটি দুটি ধাপে করতে পারি, প্রথম সম্পত্তি দ্বারা প্রথম ফিল্টার করুন এবং তারপরে দ্বিতীয় ফিল্টার দ্বারা সংমিশ্রণ করতে পারি:

$scope.filterd = $filter('filter')($scope.empList, { dept: "account" });
$scope.filterd = $scope.filterd.concat($filter('filter')($scope.empList, { dept: "sales" }));  

একাধিক সম্পত্তি ফিল্টার সহ ওয়ার্কিং ফিডল দেখুন


0

বিকল্প 1: কৌণিক সরবরাহিত ফিল্টার তুলনামূলক পরামিতি ব্যবহার করে

// declaring a comparator method
$scope.filterBy = function(actual, expected) {
    return _.contains(expected, actual); // uses underscore library contains method
};

var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];

// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')(employees, {name: ['a','c']}, $scope.filterBy);

বিকল্প 2: কৌণিক সরবরাহিত ফিল্টার অবহেলা ব্যবহার করে

var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];

// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')($filter('filter')(employees, {name: '!d'}), {name: '!b'});


-15

সর্বোত্তম উত্তরটি হ'ল:

filter:({genres: 'Action', genres: 'Comedy'}

5
এটি কি 'কমেডি' তে ফিল্টার করে না?
ব্যবহারকারী 1135469

2
আমি এটি চেষ্টা করেছিলাম এবং এটি কেবল 'কমেডি' তে ফিল্টার করে, 'অ্যাকশন'-তে নয়।
বেন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.