2013-10-16 3 views
14

Ich versuche, einen angularjs benutzerdefinierten Filter zu schreiben, der überprüft, ob ein Array von Ländern einen vom Benutzer eingegebenen Suchstring enthält.Wie schreibe ich einen angularjs Filter, um nach Stringfragmenten/Sequenzen von Strings zu suchen

Die Zeichenfolge kann aus einem Buchstaben (z. B. "E") oder einem Fragment aus n-Buchstaben (z. B. "lan") oder einem ganzen Wort (z. B. "England") bestehen.

In jedem Fall sollten alle Länder, die diesen einen Buchstaben oder dieses Fragment enthalten, zurückgegeben werden, so würde "E" "England", "Estland" usw. zurückgeben, während "lan" "England", "Irland", zurückkehren würde.

usw.

Bisher mein Filter gibt das ganze Land oder einzelne Buchstaben, aber ich habe Probleme mit String-Fragmente:

  1. HTML-Vorlage:

    <input ng-model="filter.text" type="search" placeholder="Filter..."/> 
    
    <ul> 
        <li ng-repeat="item in data | listfilter:filter.text"> 
    </ul> 
    
  2. AngularJS

    angular.module('sgComponents').filter('listfilter',[ function() { 
    return function(items, searchText) { 
        var filtered = [];    
    
        angular.forEach(items, function(item) { 
         if(item.label === searchText) { // matches whole word, e.g. 'England' 
          filtered.push(item); 
         } 
         var letters = item.label.split(''); 
         _.each(letters, function(letter) { 
          if (letter === searchText) { // matches single letter, e.g. 'E' 
           console.log('pushing'); 
           filtered.push(item); 
          } 
         }); 
         // code to match letter fragments, e.g. 'lan' 
        }); 
        return filtered; 
    }; 
    }]); 
    

Antwort

24

Es ist viel einfacher als das, verwenden Sie die String.indexOf() Funktion:

angular.forEach(items, function(item) { 
    if(item.label.indexOf(searchText) >= 0) filtered.push(item); 
}); 

Sie können beide ZeichenfolgendrehenGroß- und Kleinschreibung Anpassung zu tun:

searchText = searchText.toLowerCase(); 
angular.forEach(items, function(item) { 
    if(item.label.toLowerCase().indexOf(searchText) >= 0) filtered.push(item); 
}); 
+0

perfekt! Danke vielmals. Ich musste dies tun, wie Sie es empfehlen: if (item.label.toLowerCase(). IndexOf (searchText.toLowerCase())> = 0) filtered.push (Element); – Tone

0

Werfen Sie einen Blick auf die Angular-UI-Bootstrap-Direktive für typeahead ist es genau das, was Sie wollen: http://angular-ui.github.io/bootstrap/#/typeahead

+0

Danke für die Antwort, aber leider bin ich nicht mit Winkel-ui – Tone

+3

FWIW, eckig-ui ist kein Entwicklungs-Framework wie jQuery-ui, die Sie sein müssen " mit '. Es ist ein Satz von Teilen, die Sie nach Bedarf bereitstellen können, ohne dass Sie Ihre App anderweitig ändern müssen. – XML

7
angular.module('sgComponents').filter('listfilter',[ function() { 
    return function(items, searchText) { 
     var filtered = []; 
     var regex = new RegExp(".*" + searchItem + ".*", "ig"); 
     angular.forEach(items, function(item) { 
      if(regex.test(item)){ 
       filtered.push(item); 
      } 
     }); 
     return filtered; 
    } 
}]); 
+1

Tun Sie das nicht: es ist sehr langsam. Bitte verschieben Sie zumindest 'var regex = new RegExp (". * "+ SearchItem +". * "," Ig ")' vor der Schleife. Ein besserer Ansatz besteht jedoch darin, anstelle von RegExp 'indexOf' zu verwenden. – kseb

+0

danke für die Antwort. Nikos 'indexOf() Lösung erwies sich als am einfachsten zu implementieren. – Tone

Verwandte Themen