AngularJS (या संबंध में) में कई विशिष्ट मॉडल गुणों द्वारा फ़िल्टरिंग


107

उदाहरण यहाँ देखें: http://docs.angularjs.org/api/ng.filter:filter

आप फोन के किसी भी गुण का उपयोग करके <input ng-model="search">खोज कर सकते हैं और आप केवल नाम का उपयोग करके खोज कर सकते हैं <input ng-model="search.name">, और परिणाम उचित रूप से नाम से फ़िल्टर किए जाते हैं (फोन नंबर में टाइप करने से कोई परिणाम नहीं मिलता है, जैसा कि अपेक्षित है)।

चलो मैं एक "नाम" संपत्ति, एक "फ़ोन" संपत्ति है, और एक "गुप्त" संपत्ति के साथ एक मॉडल है, मैं कैसे द्वारा फ़िल्टर करने के बारे में जाना कहते हैं कि दोनों "फोन" गुण और "नाम" और नहीं "गुप्त" संपत्ति ? तो संक्षेप में, उपयोगकर्ता एक नाम या फोन नंबर टाइप कर सकता है और ng-repeatसही तरीके से फ़िल्टर कर सकता है, लेकिन भले ही उपयोगकर्ता एक "गुप्त" मूल्य के बराबर हिस्से में टाइप किया हो, यह कुछ भी वापस नहीं करेगा।

धन्यवाद।


हुह, मैं वास्तव में उलझन में हूँ कि इनपुट फ़ील्ड के लिए " INPUT फ़ील्ड में ng-modelनिर्दिष्ट " वस्तु को "नाम" ऑब्जेक्ट में संलग्न करने के परिणामस्वरूप वस्तुओं को उनकी संपत्ति द्वारा बार-बार कैसे फ़िल्टर किया जाएगा ? यानी मेरे लिए सहज रूप से, आपको अपने फ़िल्टर में निर्दिष्ट करके विशेष रूप से फ़िल्टर करने में सक्षम होना चाहिए : `लिखने के बजाय` <इनपुट एनजी-मॉडल = "search.name"> ...search.nameng-modelnamenameng-repeatfilter: friend.name
LazerSharks

जवाबों:


171

यहां प्लंकर है

क्लीनर कोड के साथ नया प्लंकर और जहां क्वेरी और खोज सूची आइटम दोनों असंवेदनशील हैं

इस उद्देश्य को प्राप्त करने के लिए मुख्य विचार एक फिल्टर फ़ंक्शन बनाता है।

से आधिकारिक दस्तावेज़

फ़ंक्शन: एक विधेय फ़ंक्शन का उपयोग मनमाने ढंग से फ़िल्टर लिखने के लिए किया जा सकता है। फ़ंक्शन सरणी के प्रत्येक तत्व के लिए कहा जाता है। अंतिम परिणाम उन तत्वों की एक सरणी है जो विधेय के लिए सही लौटा है।

<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नए खोज परिवर्तन की निगरानी के लिए इनपुट में जोड़ते हैं

और फिर फ़िल्टर फ़ंक्शन को ट्रिगर करें।


1
हाय @ मक्सिसम, क्या आप बता सकते हैं कि दोहरी ऊर्ध्वाधर रेखाओं का क्या अर्थ है? मुझे यकीन नहीं है कि इस पंक्ति को कैसे पढ़ा जाए:item.brand.indexOf($scope.query)!=-1 || item.model.indexOf($scope.query)!=-1)
लेज़रशर्क्स

15
|| का मतलब है। आप जावास्क्रिप्ट, अच्छे भागों को पढ़ना चाह सकते हैं।
मैक्सिमम

1
की बात कर रहा हूँ, बस यह कोशिश की और यह काम करता है: <tr ng-repeat = "स्मार्टफोन में स्मार्टफोन | फ़िल्टर: फोन" नाम ">। पहला फिल्टर पूर्वता लेता है।
झाझी

2
@kate angular.lowercase (item.brand) .indexOf ... मूल रूप से, बस निचला मामला ही सब कुछ है
अधिकतम

1
@maxisam। सही तरीके से काम करने की असंवेदनशीलता के लिए क्वेरी स्ट्रिंग को कम करने की आवश्यकता होती है। यहाँ काम के मामले में असंवेदनशीलता के साथ आप का एक कांटा हैplnkr.co/edit/auz02bvWm1Vw4eItSa5J?p= फ़िल्टर के लिए धन्यवाद।
लियोपोल्ड क्रिस्टजेंसन

78

आप किसी ऑब्जेक्ट को अपनी फ़िल्टर अभिव्यक्ति के पैरामीटर के रूप में पास कर सकते हैं, जैसा कि एपीआई संदर्भ में वर्णित है । यह ऑब्जेक्ट चुनिंदा गुणों को लागू कर सकता है, जिसमें आप रुचि रखते हैं, जैसे:

<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 तक रिलीज़ होने तक @ मैक्सिसम के समाधान का उपयोग करना चाह सकते हैं।


26
अपने प्लंकर को देखते हुए कि यदि आपके पास केवल एक खोज बॉक्स है तो वांछित प्रभाव कैसे प्राप्त किया जाएगा। यह चुनौती है ... या हिस्सा।
सिल्वस्टर 27

2
यह उत्तर सोना है लेकिन सिर्फ सवाल का जवाब नहीं है।
सिरिल चैपॉन

1
आप तालिका में इस उदाहरण में केवल एक इनपुट फ़ील्ड के साथ इसे कैसे करेंगे: datatables.net
फ्लैश

आप पोस्ट किए गए प्लंकर में फ़िल्टर किए गए डेटा की गिनती कैसे प्राप्त करेंगे?
मुहम्मद जीशान ताहिर

5

मैंने @ मैक्सिसम के उत्तर से खुद को प्रेरित किया और अपना खुद का प्रकार्य बनाया और मैं इसे साझा करूँगा (क्यूज़ मैं ऊब चुका हूँ)।

स्थिति मैं कारों की एक सरणी के माध्यम से फ़िल्टर करना चाहते हैं। फ़िल्टर करने के लिए चयनित गुण नाम, वर्ष, मूल्य और किमी हैं। संपत्ति की कीमत और किमी संख्या हैं (इसलिए उपयोग .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;
    };

1
क्या आप दिखा सकते हैं कि किस तरह से, आप इस फिल्टर को कोणीय में कहते हैं?
ट्विनकाब

5

यदि आप तीसरे पक्ष के पुस्तकालयों का उपयोग करने के लिए खुले हैं, तो फिल्टर का एक अच्छा संग्रह के साथ 'कोणीय फिल्टर' उपयोगी हो सकता है:

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

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


2

यहाँ अच्छे समाधानों का एक समूह है, लेकिन मेरा सुझाव है कि इसके साथ अन्य मार्ग जाना चाहिए। यदि खोज सबसे महत्वपूर्ण चीज है और 'गुप्त' संपत्ति का उपयोग दृश्य पर नहीं किया जाता है; इसके लिए मेरा दृष्टिकोण अपने सभी लाभों के साथ अंतर्निहित कोणीय फिल्टर का उपयोग करना होगा और बस मॉडल को वस्तुओं के एक नए सरणी में मैप करना होगा।

प्रश्न से उदाहरण:

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

अब, html में, इन दोनों गुणों को खोजने के लिए बस नियमित फ़िल्टर का उपयोग करें।

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

1
मुझे छोटी वस्तुओं से निपटने के लिए यह समाधान पसंद है, लेकिन अगर आपके पास बहुत सारे नेस्टेड सामान के साथ वस्तुओं का एक बड़ा सेट है, तो सब कुछ मैप करना एक त्रुटि बनाने के लिए भ्रमित / आसान हो सकता है। +1 हालांकि बुनियादी जरूरतों के लिए एक महान समाधान के लिए ... काश यह सब के बजाय केवल कुछ गुणों के लिए फ़िल्टर करने के लिए इतना जटिल नहीं था! : / ... हो सकता है कि भविष्य में कोणीय इस प्रकार के फिल्टर के लिए कुछ कार्यक्षमता में निर्मित हो सकता है ...
twknab

2

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'
      }
      ];
  })

})();

नकारात्मक पक्ष यह है कि एक और 3 पार्टी प्लगइन जोड़ता है। कॉल करने के लिए महत्वपूर्ण है।
मिक्स

2

मैंने इसे बस हल किया:

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

1

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

यहां एक मामला संवेदनशील खोज है जो आपकी खोज को शब्दों में अलग करने के साथ-साथ प्रत्येक मॉडल में खोज करने के लिए भी अलग है। केवल जब यह एक स्थान पाता है तो यह क्वेरी को एक सरणी में विभाजित करने की कोशिश करेगा और फिर प्रत्येक शब्द को खोजेगा।

यह सच है अगर हर शब्द कम से कम एक मॉडल में है।

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

1

फ़िल्टर फ़ील्ड के साथ जावास्क्रिप्ट ऑब्जेक्ट हो सकता है और आपके पास अभिव्यक्ति हो सकती है:

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

0

मैं जब संभव हो तो सरल रखना पसंद करता हूं। मुझे अंतर्राष्ट्रीय द्वारा समूह की आवश्यकता थी, सभी स्तंभों पर फ़िल्टर करें, प्रत्येक समूह के लिए गणना प्रदर्शित करें और यदि कोई आइटम मौजूद नहीं है तो समूह को छिपाएं।

प्लस मैं इस तरह से कुछ सरल के लिए एक कस्टम फ़िल्टर जोड़ना नहीं चाहता था।

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

0

मुझे बहुत देर हो सकती है लेकिन यह वही है जो मैंने किया। मैंने एक बहुत ही सामान्य फिल्टर बनाया।

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

    })

फिर इसे इस तरह इस्तेमाल करें

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

आपका सर्च बॉक्स जैसा हो

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

जहां नाम और device_id DVs में गुण हैं


-1

यहां उन लोगों के लिए सरल समाधान है जो एक वस्तु के खिलाफ एक त्वरित फ़िल्टर चाहते हैं:

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

सरणी फ़िल्टर आपको उस ऑब्जेक्ट की नकल करने देता है जिसे आप फ़िल्टर करने का प्रयास कर रहे हैं। उपरोक्त मामले में, निम्न वर्ग ठीक काम करेंगे:

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

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

और जहां डेक की तरह लग सकता है:

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

  return {
    Cards: _cards
  };
};

और यदि आप ऑब्जेक्ट के कई गुणों को फिल्ड नामों से अलग करना चाहते हैं, तो अल्पविराम द्वारा:

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

संपादित करें: यहां एक काम करने वाली तख्ती है जो एकल और कई संपत्ति फिल्टर का एक उदाहरण प्रदान करती है:

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


आप इस प्रकार की खोज को कैसे लागू करेंगे? इस उदाहरण में उनकी तालिका में आप किसी शब्द का एक भाग टाइप कर सकते हैं, स्पेस की को मार सकते हैं, और किसी कॉलम में दूसरे शब्द का भाग टाइप कर सकते हैं, और यह अभी भी तदनुसार फ़िल्टर करता है। datatables.net
फ्लैश

मुझे नहीं पता कि जब तक मैंने प्रश्न को ठीक से संबोधित नहीं किया था, तब तक मेरी पोस्ट डाउनग्रेड क्यों की गई थी। जब आप इसे सही तरीके से लागू करते हैं तो कोड काम करता है।
रिक

आपके उत्तर के लिए धन्यवाद रिक मुझे पता नहीं है कि किसने नीचे मतदान किया है, लेकिन मैं आगे जाकर इसे वापस वोट कर सकता हूं। हालाँकि उस उदाहरण में यह कैसे है कि मैंने जो लिंक दिया है उसमें एक के समान है जहां उनके पास एक खोज इनपुट फ़ील्ड है और जैसे ही वे टाइप करते हैं यह फ़िल्टर हो जाता है। : उसकी के साथ-साथ मेरी origninal पद someoune यह मतदान किया था नीचे था stackoverflow.com/questions/42421941/angular-custom-search
फ्लैश

1
मैंने एक टेक्स्टबॉक्स फ़िल्टर कैसे काम कर सकता है यह दिखाने के लिए plnkr को अपडेट किया है। ध्यान दें कि यह अपेक्षा के अनुसार किसी भी आंशिक पाठ पर कैसे फ़िल्टर करता है। मेरा मानना ​​है कि यह आपके जुड़े उदाहरण के करीब है। यदि आपको अलग-अलग फ़िल्टर (अलग-अलग डेटा टुकड़ों के लिए) की आवश्यकता है, तो यह एक अलग सवाल है।
रिक

@ मैं वास्तव में इस उदाहरण में समय लगाने के लिए आपकी सराहना करता हूं, जैसा कि वर्तमान में मैं खुद को केवल 2 गुणों को फ़िल्टर करने की कोशिश कर रहा हूं, बजाय किसी वस्तु के सभी गुणों के बजाय दोहराया जा रहा है ng-repeat। आपका उदाहरण हालांकि थोड़ा जटिल लगता है: क्या कोई तरीका है जिससे आप इसे उबाल सकते हैं? मुझे पता है कि प्रश्न अनिवार्य रूप से एक एकल खोज क्षेत्र की तलाश में है जो केवल चयनित गुणों के लिए फ़िल्टर कर सकता है। आपके उदाहरण में, ऐसा लगता है कि हम या तो अंकित मूल्य नामों या संख्याओं के लिए फ़िल्टर कर रहे हैं, लेकिन दोनों नहीं। यदि मैं आपके उदाहरण को समझने में गलत हूं, तो कृपया मुझे बताएं!
ट्विनकाब
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.