फ़िल्टर किए गए एनजी-रिपीट डेटा की लंबाई कैसे प्रदर्शित करें


438

मेरे पास एक डेटा ऐरे है जिसमें कई ऑब्जेक्ट्स (JSON फॉर्मेट) हैं। निम्नलिखित इस सरणी की सामग्री के रूप में ग्रहण किया जा सकता है:

var data = [
  {
    "name": "Jim",
    "age" : 25
  },
  {
    "name": "Jerry",
    "age": 27
  }
];

अब, मैं ये विवरण प्रदर्शित करता हूं:

<div ng-repeat="person in data | filter: query">
</div

यहां, क्वेरी को एक इनपुट फ़ील्ड के लिए बनाया गया है जिसमें उपयोगकर्ता प्रदर्शित डेटा को प्रतिबंधित कर सकता है।

अब, मेरे पास एक और स्थान है जिसमें मैं लोगों की वर्तमान गणना / व्यक्ति को प्रदर्शित करता हूं, अर्थात Showing {{data.length}} Persons

मैं जो करना चाहता हूं वह यह है कि जब उपयोगकर्ता किसी व्यक्ति को खोजता है और प्रदर्शित डेटा क्वेरी के आधार पर फ़िल्टर किया जाता है, तो Showing...personsवर्तमान में दिखाए जा रहे लोगों के मूल्य में भी परिवर्तन होता है। लेकिन ऐसा नहीं हो रहा है। यह हमेशा फ़िल्टर किए गए के बजाय डेटा में कुल व्यक्तियों को प्रदर्शित करता है - मुझे फ़िल्टर किए गए डेटा की गिनती कैसे मिलती है?

जवाबों:


746

कोणीय 1.3+ के लिए ( @Tom को क्रेडिट)

एक अन्य अभिव्यक्ति का उपयोग करें (डॉक्स: कोणीय 1.3.0: एनकैपिट , आर्ग्युमेंट सेक्शन तक स्क्रॉल करें ):

<div ng-repeat="person in data | filter:query as filtered">
</div>

1.3 से पहले कोणीय के लिए

परिणामों को एक नए चर (जैसे filtered) में निर्दिष्ट करें और इसे एक्सेस करें:

<div ng-repeat="person in filtered = (data | filter: query)">
</div>

परिणामों की संख्या प्रदर्शित करें:

Showing {{filtered.length}} Persons

एक समान उदाहरण फिडेल । श्रेय पावेल कोज़लोव्स्की को जाता है


42
यह सरल उत्तर है जो फ़िल्टर निष्पादन को नहीं दोहराता है।
agmin

3
@ बान: हाँ। आप नियंत्रक का उपयोग करके इसे एक्सेस कर सकते हैं $scope.filtered.length
वूम्स

2
यह मेरे लिए काम नहीं करता है। लॉग undefined, संभावना है क्योंकि इसे लॉग करने के समय, चर अभी तक परिभाषित नहीं किया गया है। तो चर को परिभाषित करने और फ़िल्टर को दृश्य में लागू करने के बाद मैं यह कैसे सुनिश्चित करूंगा कि नियंत्रक में कोड है ?
बेन

6
@Ben: मुझे लगता है कि यह बंद विषय जा रहा है। मैं jsfiddle जैसे एक कस्टम फ़िल्टर बनाने पर विचार करूंगा , हालाँकि, आप इसे कंट्रोलर के अंदर भी देख सकते हैं:$scope.$watch('filtered', function() { console.log('filtered:', $scope.filtered); });
Wumms

3
अगर मैं लिमिट जोड़ना चाहता था तो 1.3+ वर्जन काम नहीं करता था person in data | filter:query as filtered | limitTo:5:। इसलिए मुझे 1.3 संस्करण से पहले का उपयोग करना था:person in filtered = (data | filter: query) | limitTo: 5
बेंजोविक

332

पूर्णता के लिए, पिछले उत्तरों (नियंत्रक के अंदर दृश्यमान लोगों की गणना करें) के अलावा, आप अपने HTML टेम्पलेट में भी गणना नीचे के उदाहरण के अनुसार कर सकते हैं।

मान लें कि आपकी लोगों की सूची dataपरिवर्तनशील है और आप queryमॉडल का उपयोग करके लोगों को फ़िल्टर करते हैं , तो निम्न कोड आपके लिए काम करेगा:

<p>Number of visible people: {{(data|filter:query).length}}</p>
<p>Total number of people: {{data.length}}</p>
  • {{data.length}} - कुल लोगों की संख्या प्रिंट करता है
  • {{(data|filter:query).length}} - प्रिंट लोगों की संख्या फ़िल्टर किया गया

ध्यान दें कि यह समाधान ठीक काम करता है यदि आप किसी पृष्ठ में केवल एक बार फ़िल्टर किए गए डेटा का उपयोग करना चाहते हैं । हालांकि, अगर आप एक बार जैसे की तुलना में अधिक वर्तमान आइटम के लिए फ़िल्टर का उपयोग डेटा और सूची से फ़िल्टर की लंबाई को दिखाने के लिए, मैं का उपयोग कर सुझाव है उर्फ अभिव्यक्ति AngularJS के लिए (नीचे वर्णित) 1.3+ या समाधान द्वारा प्रस्तावित @Wumms AngularJS संस्करण 1.3 से पहले के लिए।

कोणीय 1.3 में नई सुविधा

AngularJS रचनाकारों ने उस समस्या पर भी ध्यान दिया और संस्करण 1.3 (बीटा 17) में उन्होंने "उर्फ" अभिव्यक्ति को जोड़ा, जो फ़िल्टर लागू होने के बाद पुनरावर्तक के मध्यवर्ती परिणामों को संग्रहीत करेगा जैसे

<div ng-repeat="person in data | filter:query as results">
    <!-- template ... -->
</div>

<p>Number of visible people: {{results.length}}</p>

उर्फ अभिव्यक्ति कई फिल्टर निष्पादन मुद्दा नहीं कर पाएगा।

मुझे उम्मीद है कि इससे मदद मिलेगी।


4
क्या इसका मतलब यह होगा कि फ़िल्टर दो बार निष्पादित किया गया है?
फ्लैश '

9
हां, इसे दो बार निष्पादित किया जाता है।
नाथनचाहिल

11
इससे पहले कि आप इस एक का उपयोग करने का फैसला आप @Wumms जवाब पढ़ें यह सुनिश्चित कर लें (और आप नहीं होगा) ...
epeleg

1
कोई बात नहीं, मुझे लगता है कि उत्तर में उर्फ ​​अभिव्यक्ति के बारे में कोई हिस्सा नहीं था जब आपने अपनी टिप्पणी की थी।
एडम गुडविन

2
यह उत्तर वर्तमान शीर्ष उत्तर के विपरीत कई फ़िल्टर अभिव्यक्तियों का समर्थन करता है। यानी){{(data|filter:query|filter:query2).length}}
चक्र

45

अगर आपके पास सबसे आसान तरीका है

<div ng-repeat="person in data | filter: query"></div>

फ़िल्टर्ड डेटा लंबाई

<div>{{ (data | filter: query).length }}</div>

यह कोणीय बर्तनों का उपयोग करने वाले किसी भी व्यक्ति के लिए सबसे उपयोगी है, अलियासिंग और पूर्व एनजी-1.3 विकल्प का समर्थन नहीं किया जाता है।
pcnate

क्या यह दो बार डेटा की गणना करेगा?
Jeppe

36

ngRepeat एक फ़िल्टर लागू करते समय सरणी की एक प्रति बनाता है, इसलिए आप केवल फ़िल्टर किए गए तत्वों को संदर्भित करने के लिए स्रोत सरणी का उपयोग नहीं कर सकते।

आपके मामले में, $filterसेवा का उपयोग करके अपने नियंत्रक के अंदर फ़िल्टर लागू करना बेहतर हो सकता है :

function MainCtrl( $scope, filterFilter ) {
  // ...

  $scope.filteredData = myNormalData;

  $scope.$watch( 'myInputModel', function ( val ) {
    $scope.filteredData = filterFilter( myNormalData, val );
  });

  // ...
}

और फिर आप filteredDataइसके बजाय अपने विचार में संपत्ति का उपयोग करते हैं। यहां एक कार्यशील प्लंकर है: http://plnkr.co/edit/7c1l24rPkuKPOS5o2qtx?p=preview


1
जो मुझे समझ में आया वह यह है कि मैं {{filteredData.length}}इसके बजाय उपयोग करता हूं data.length। मुझे यह भी समझ आया कि myInputModelइनपुट क्वेरी के लिए मैप किया गया मॉडल है जो डेटा को फ़िल्टर करता है। valवह पाठ होगा जो इनपुट में टाइप किया जाता है (मूल रूप से क्वेरी) लेकिन हर बार जब मैं टाइप करता हूं, तो यह बदल जाता है। लेकिन filterFilterयहाँ क्या है ? मैं जोड़ सकता हूं कि मेरे पास अपना स्वयं का कस्टमफ़िल्टर है (जिसमें मैं निर्दिष्ट कर सकता हूं कि फ़िल्टर करने के लिए ऑब्जेक्ट की कौन सी कुंजी पर विचार करें)।
user109187

ये सही है। इसके अलावा बस का उपयोग करें ng-repeat="person in filteredData"क्योंकि दो बार इसे छानने का कोई अर्थ नहीं है। साथ $filter: सेवा, तो आप सिर्फ "फ़िल्टर", जैसे के साथ प्रत्यय लगाना द्वारा एक विशेष फिल्टर के लिए पूछ सकते dateFilter, jsonFilter,, आदि आप अपने स्वयं के कस्टम फिल्टर का उपयोग कर रहे हैं, तो बस का उपयोग करने वाले सामान्य के बजाय एक filterFilter
जोश डेविड मिलर

एक एनजी-रिपीट में कई फिल्टर लगाने के बारे में, मान लें कि आपके पास मान और एक पाठ इनपुट फ़ील्ड के साथ 2 ड्रॉपडाउन हैं?
कीमियागर

फ़िल्टर केवल एक फ़ंक्शन है, इसलिए आप पहले फ़िल्टर के आउटपुट को दूसरे फ़िल्टर में पास करेंगे।
जोश डेविड मिलर

29

AngularJS 1.3 के बाद से आप उपनाम का उपयोग कर सकते हैं:

item in items | filter:x as results

और कहीं:

<span>Total {{results.length}} result(s).</span>

से डॉक्स :

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

उदाहरण के लिए: आइटम में आइटम | फ़िल्टर: x परिणाम के रूप में दोहराए गए आइटम के टुकड़े को परिणाम के रूप में संग्रहीत करेगा, लेकिन फ़िल्टर के माध्यम से आइटम संसाधित होने के बाद ही।


मैं $scope.$watchइस अलियास किए गए परिणाम पर लागू नहीं हो पा रहा हूं । $broadcastअलियास resultsचर के लिए कोई सुझाव ?
डेब्यू किया

25

यह भी ध्यान रखना उपयोगी है कि आप फ़िल्टर को समूहीकृत करके परिणामों के कई स्तरों को संग्रहीत कर सकते हैं

all items: {{items.length}}
filtered items: {{filteredItems.length}}
limited and filtered items: {{limitedAndFilteredItems.length}}
<div ng-repeat="item in limitedAndFilteredItems = (filteredItems = (items | filter:search) | limitTo:25)">...</div>

यहाँ एक डेमो फिडल है


13

यहाँ काम किया उदाहरण देखें प्लंकर पर देखें

  <body ng-controller="MainCtrl">
    <input ng-model="search" type="text">
    <br>
    Showing {{data.length}} Persons; <br>
    Filtered {{counted}}
    <ul>
      <li ng-repeat="person in data | filter:search">
        {{person.name}}
      </li>
    </ul>
  </body>

<script> 
var app = angular.module('angularjs-starter', [])

app.controller('MainCtrl', function($scope, $filter) {
  $scope.data = [
    {
      "name": "Jim", "age" : 21
    }, {
      "name": "Jerry", "age": 26
    }, {
      "name": "Alex",  "age" : 25
    }, {
      "name": "Max", "age": 22
    }
  ];

  $scope.counted = $scope.data.length; 
  $scope.$watch("search", function(query){
    $scope.counted = $filter("filter")($scope.data, query).length;
  });
});


4
इस दृष्टिकोण के साथ समस्या यह है कि आप फ़िल्टर को दो बार चला रहे हैं: एक बार ngRepeat में और एक बार नियंत्रक में।
जोश डेविड मिलर

हाँ, आप सही हैं, क्या आप अपने जवाब के आधार पर अपने काम के उदाहरण को पोस्ट कर सकते हैं, मैं थोड़ा और फिल्टर सीखना चाहूंगा? धन्यवाद।
मकिस्म

2
ज़रूर। यहां काम कर रहा प्लंकर: plnkr.co/edit/7c1l24rPkuKPOS5o2qtx?p=preview है । मैंने अभी तुम्हारा संपादन किया है।
जोश डेविड मिलर

10

आप इसे 2 तरीकों से कर सकते हैं । में टेम्पलेट और में नियंत्रक । टेम्प्लेट में आप अपने फ़िल्टर किए गए ऐरे को दूसरे वेरिएबल पर सेट कर सकते हैं, फिर उसे वैसे ही इस्तेमाल करें जैसे आप चाहते हैं। यहां है कि इसे कैसे करना है:

<ul>
  <li data-ng-repeat="user in usersList = (users | gender:filterGender)" data-ng-bind="user.name"></li>
</ul>
 ....
<span>{{ usersList.length | number }}</span>

यदि आपको उदाहरणों की आवश्यकता है, तो AngularJs फ़िल्टर्ड काउंट उदाहरण / डेमो देखें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.