2016-04-20 11 views
0

Ich benutze die eckige advanced search box und ich möchte einen benutzerdefinierten Filter in meiner eckigen Seite implementieren, aber ich habe Probleme herauszufinden, wie man eine Reihe von Anforderungen in einer Abfrage zu behandeln. Lassen Sie uns sagen, dass ich mehrere Objekte, die das folgende Format folgen:Angular Implementieren Multi-Suchfilter

{ 
    "displayName":"John", 
    "gender":"male", 
    "type":"customer", 
    "items": 3, 
} 

Ich möchte der Lage sein, in einfachem Englisch `Wer zu suchen, dessen Name John ist und ist vom Typ Kunde“ Hier ist meine Winkelsuchcode so. weit:

app.filter('infoFilter', function() { 
    return function(data, query) { 
     var output = []; 
     var index; 

     //loop over the original array 
     angular.forEach(data, function(row, index) { 
      angular.forEach(query, function(input, value) { 
       if(input) { 
        if(angular.isNumber(row[value]) && row[value] == input) { 
         output.push(row); 
        } else if(!angular.isNumber(row[value]) && row[value].toLowerCase().indexOf(input.toLowerCase()) > -1) { 
         output.push(row); 
        } 
       } 
      }); 
     }); 
     if(query) { 
      return data; 
     } else { 
      return output; 
     } 
    } 
}); 

Die Abfrage kommt als ein Objekt, das wie folgt aussieht:.

{ 
    "displayName":"John" 
} 

diese völlig in Ordnung für 1 Suchparameter funktioniert Also, wenn ich fürgesuchtMeine Tabelle wird aktualisiert, um alle Einträge mit dem Namen John anzuzeigen. Dies würde jedoch für Multi-Search-Parameter nicht wirklich funktionieren. Also, wenn die Abfrage sah wie folgt aus:

{ 
    "displayName":"John", 
    "gender":"Female" 
} 

Ich brauche sofort alle Parameter anzuwenden, bevor ich output.push(row) tun. Wie genau würde ich das machen?

+0

diese mehrere Parameter sollten in welcher Weise UND/ODER Bedingung funktionieren ..? Der einzelne Datensatz sollte mit beiden Abfragen übereinstimmen, oder jeder Datensatz enthält einen dieser Datensätze. –

Antwort

3

Wenn ich Sie richtig verstehe, möchten Sie die Zeilen filtern, in denen alle Abfrageparameter gelten (UND). Ich habe Ihren Code geringfügig geändert, um dieses Verhalten zu erreichen.

app.filter('infoFilter', function() { 
    return function(data, query) { 
     var output = []; 
     var index; 

     //loop over the original array 
     angular.forEach(data, function(row, index) { 

      var pushRow = true; 

      angular.forEach(query, function(input, value) { 
       if(input) { 
        if(angular.isNumber(row[value]) && row[value] == input) { 
         return; 
        } else if(!angular.isNumber(row[value]) && row[value].toLowerCase().indexOf(input.toLowerCase()) > -1) { 
         return; 
        } 
       } 
       pushRow = false; 
      }); 

      if (pushRow) { 
       output.push(row); 
      } 
     }); 

     // This bit also seems to be the wrong way around in your code. 
     if(!query) { 
      return data; 
     } else { 
      return output; 
     } 
    } 
}); 

Edit:

Hier ist auch eine optimierte Version des gleichen Filters javascripts mit built in array functions.

app.filter('infoFilter', function() { 
    return function(data, query) { 
     if(!query || !data) { 
      return data; 
     } 

     return data.filter(function(row) { 
      return Object.keys(query).every(function(key) { 
       var rowValue = row[key]; 
       var queryValue = query[key]; 

       return (angular.isNumber(rowValue) && rowValue == input) || 
         (angular.isString(rowValue) && rowValue.toLowerCase().indexOf(queryValue.toLowerCase()) > -1); 
      }); 
     }); 
    }; 
}); 
+0

das ist perfekt, aber aus irgendeinem Grund bekomme ich immer den Fehler 'TypeError: Kann Eigenschaft 'Filter' von undefined nicht lesen. Irgendeine Idee, worum es geht? – Richard

+0

Wahrscheinlich, weil Daten nicht definiert sind. – Scraph

+0

Ich habe den Code aktualisiert, um das jetzt zu handhaben. – Scraph