2017-11-29 2 views
1

Gerade jetzt meine Datenstruktur wieFilter das Objekt in dem Array durch dynamische Filter - AngularJS

ist
product = [{att1:'2',att2:'red',att3:'gold'}, 
    {att1:'1',att2:'blue',att3:'wood'}, 
    {att1:'2',att2:'green',att3:'plastic'}, 
    {att1:'1',att2:'red',att3:'plastic'}] 

Und ich habe einen Filter auf der Web-Seite, es hat drei Teile: att1, att2, att3. Der Benutzer muss nicht für jedes Teil Optionen auswählen.

  • Für Filter att1 hat es 2 Optionen: "1" und "2".
  • Filter att2 es hat 2 Optionen: "rot" "blau" und "grün"
  • Filter att3 es hat 3 Optionen: "Gold", "Holz" und "Kunststoff".

Ich kann die Optionen erhalten, die ausgewählt sind. Zum Beispiel: {att1:['2'],att3:['gold','plastic']} oder {att1:['1']}

Meine Frage ist, wie verwende ich product.filter die Produktdaten zu filtern? Danke!

+0

bitte formatieren Sie Ihre Frage –

+0

Sie sind auf der Suche Wie schreibe ich einen benutzerdefinierten $ Filter oder versuchen Sie die Array Filter Funktion zu benutzen? nicht wirklich klar, was hier gefragt wird oder wo du feststeckst. – shaunhusain

+0

@shaunhusain Die Situation ist manchmal der Benutzer wählt die Option unter "att1" manchmal nicht. Die Filterfunktion kann also keinen harten Code verwenden, um Produktdaten zu filtern, weil sie 'att1 === '1'' oder' att1 === '1' && att2 === 'red'' oder' (att1 ===') zurückgeben kann. 1 '|| att1 ===' 2 ') && (att2 ===' grün '|| att2 ===' rot ') && att3 ===' gold'' irgendwann ist es dynamisch. – molly12345

Antwort

1

können Sie eine benutzerdefinierte Filterfunktion benutzen, die einfach zu bedienen ist, benutzte ich att1 aber man kann es auf alle Felder erweitern:

var app = angular.module("MyApp", []); 
 

 
app.controller("MyCtrl", function($scope) { 
 
    $scope.products = [{att1:'2',att2:'red',att3:'gold'}, 
 
    {att1:'1',att2:'blue',att3:'wood'}, 
 
    {att1:'2',att2:'green',att3:'plastic'}, 
 
    {att1:'1',att2:'red',att3:'plastic'}]; 
 

 
    $scope.filterFunction = function(element) { 
 
    return element.att1.match(/^Ma/) ? true : false; 
 
    }; 
 

 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<div ng-app="MyApp"> 
 
    <div ng-controller="MyCtrl"> 
 
    <form class="form-inline"> 
 
     <input ng-model="query" type="text" 
 
     placeholder="Filter by" autofocus> 
 
    </form> 
 
    <ul ng-repeat="product in products | filter:query"> 
 
     <li>{{product}}</li> 
 
    </ul> 
 
    
 
    
 
    <ul ng-repeat="product in products | filter:filterFunction"> 
 
     <li>{{product}}</li> 
 
    </ul> 
 
    </div> 
 
</div>

+0

filterFunction definiert, aber nicht referenziert? – shaunhusain

+0

oh, meine schlechte, jetzt behoben @shaunhusain – Yaser

+0

Alles gut, nur um hinzuzufügen, könnte die Filterfunktion wie 'angular.filter ('productFilter', function() {Return-Funktion filterFunction (Eingabe, arg)) {/ * Ihre Filterung code gibt ein neues Array mit den gefilterten Werten * /}}) 'zurück und benutzt es dann wie' product in products | productFilter' https://docs.angularjs.org/guide/filter#creating-custom-filters Sie können auch alle Filterfunktionen mit Hilfe des $ filter service aufrufen wie 'var prodFilterFn = $ filter ('productFilter');' – shaunhusain

0

Ich schlug sich die besondere Logik für diese eine, die drei verschachtelten Schleifen zu verwenden, ist nicht super, aber es macht den Job. Ich bin sicher, dass Sie dies durch Verwendung einiger Karten oder etwas optimieren können, aber ich ging einfach mit dem es durch Brute-Force-Ansatz getan :)

angular.module('myApp',[]) 
 
    .service('ProductService', function(){ 
 
    return { 
 
     products:[ 
 
     {att1:'2',att2:'red',att3:'gold'}, 
 
     {att1:'1',att2:'blue',att3:'wood'}, 
 
     {att1:'2',att2:'green',att3:'plastic'}, 
 
     {att1:'1',att2:'red',att3:'plastic'} 
 
     ] 
 
    } 
 
    }) 
 
    
 
    .controller('TestCtrl', function(ProductService){ 
 
    this.ProductService = ProductService; 
 
    this.filterObject1 = {att1:['2'],att3:['gold','plastic']}; 
 
    this.filterObject2 = {att1:['1']}; 
 
    }) 
 
    
 
    .filter('productFilter', function(){ 
 
    return function(input,filterObj){ 
 
     if(!filterObj){ 
 
     return input; 
 
     } 
 
     var newArray = []; 
 
     var filterKeys = Object.keys(filterObj); 
 
     
 
     for(var i=0;i<input.length;i++){ 
 
     var curElement = input[i]; 
 
     innerLoops: 
 
     for(var j=0;j<filterKeys.length;j++){ 
 
      var curKey= filterKeys[j]; 
 
      for(var k=0;k<filterObj[curKey].length;k++){ 
 
      var curFilterValue = filterObj[curKey][k]; 
 
      if(curElement[curKey].match(curFilterValue)){ 
 
       //We found a match keep this element and move on to checking the next one by breaking out of the inner loops that are checking particular keys/values 
 
       newArray.push(curElement); 
 
       break innerLoops; 
 
      } 
 
      } 
 
     } 
 
     } 
 
     return newArray; 
 
    }; 
 
    }) 
 
    ;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script> 
 

 
<div ng-app="myApp" ng-controller="TestCtrl as ctrl"> 
 
Unfiltered 
 
    <div ng-repeat="product in ctrl.ProductService.products|productFilter"> 
 
    {{product}} 
 
    </div> 
 
    <hr/> 
 
    <strong>Filtered with: {{ctrl.filterObject1}}</strong> 
 
    <div ng-repeat="product in ctrl.ProductService.products|productFilter:ctrl.filterObject1"> 
 
    {{product}} 
 
    </div> 
 
    <hr/> 
 
    <strong>Filtered with {{ctrl.filterObject2}}</strong> 
 
    <div ng-repeat="product in ctrl.ProductService.products|productFilter:ctrl.filterObject2"> 
 
    {{product}} 
 
    </div> 
 
</div>