2014-07-21 3 views
12

J'ai un formulaire avec plusieurs filtres mais pour certains, j'ai besoin d'une comparaison stricte.AngularJS filtre strict sur un seul champ

tl; dr: comparaison stricte pour user_id pas pour firstname.

<select ng-model="search.user_id"> 
    <option value="1">1</option> 
    <option value="2">2</option> 
    <option value="10">10</option> 
    <option value="11">11</option> 
    <option value="23">23</option> 
</select> 

<input type="text" ng-model="search.firstname"> 

<ul> 
    <li ng-repeat="user in users | filter:search">#{{ user.user_id }} {{ user.firstname}}</li> 
</ul> 

J'ai essayé le troisième paramètre true mais il fonctionne également pour le filtre firstname.

Le problème est: si vous sélectionnez la valeur 2, tous les utilisateurs ayant un 2 dans leur ID seront filtrés, je ne veux pas ce comportement.

Voici le fiddle.

+2

créer un filtre personnalisé – charlietfl

Répondre

15

j'ai essayé de le réparer nativement, plutôt que des filtres personnalisés, son travail, voici la PLUNKER LINK

a dû spécifier plusieurs filtres tag

<li ng-repeat="user in users | filter:{'user_id': search.user_id}: true | filter: {'firstname' : search.firstname}"> 

mais il y a quelques mises en garde:

  1. je devais changer le type de numéro à chaîne ...

  2. si je remis à zéro la valeur de correspondance exacte cela ne fonctionne pas ...

donc je devais écrire un filer personnalisé qui fonctionne pour correspondance exacte & ignore les valeurs vides/null

$scope.filter2 = function(field1, field2) { 
    if(field2 === "" || field2 === null) return true; 
    return field1 === field2; 
}; 

vous trouverez tous les deux dans le lien fourni plunker

1

Vous pourriez avoir une fonction comme celui-ci dans votre contrôleur

$scope.identical = function(actual, expected){ 
    return actual === parseInt(expected); 
} 

et vous pouvez l'utiliser comme ceci

<li ng-repeat="user in users | filter:search.user_id:identical"> 
+0

Cela ne filtrent pas la 'firstname'. – runTarm

+0

Je crois qu'il écrit "comparaison stricte pour user_id pas pour prénom". Et je crois que la syntaxe fonctionnera puisque je l'ai essayé dans son propre violon. – Edminsson

+0

J'ai déjà supprimé la phrase de syntaxe de mon commentaire, ma mauvaise ne pas tester avant de commenter! Pour la 'comparaison stricte pour user_id pas pour firstname', je ne sais pas exactement ce dont l'OP a besoin, mais mon interprétation est qu'il veut filtrer à la fois' user_id' et 'firstname' mais utiliser la comparaison stricte sur' user_id' seulement. – runTarm

0

Changement de votre code html:

<li ng-repeat="user in users | filter:f">#{{ user.user_id }} {{ user.firstname}}</li> 

Je suppose vous voulez and si les deux valeurs sont présentes. Changez-le en or si vous en avez besoin. fonction de filtre personnalisée:

$scope.f = function(val) { 
    var hasUserId = $scope.search.user_id; 
    var hasName = $scope.search.firstname; 

    var firstNameMatch = function() { return val.firstname.indexOf($scope.search.firstname) > -1 }; 
    var userIdMatch = function() { return $scope.search.user_id == val.user_id }; 

    if(hasUserId && hasName) { 
     return firstNameMatch() && userIdMatch() 
    } else if (hasUserId) { 
     return userIdMatch(); 
    } else if (hasName) { 
     return firstNameMatch(); 
    } 
    return true; 
}; 

Encore un changement à votre contrôleur:

$scope.search= {}; 

Forked Fiddle.

1

Depuis que je ne peux pas commenter les réponses des autres, je vais le faire de cette façon.

J'ai utilisé la solution de HarisR mais je l'ai modifiée pour qu'elle puisse être utilisée avec des nombres aussi si vous avez besoin de votre valeur numérique.

$scope.filter2 = function(field1, field2) { 
    if(field2 === "" || field2 === null) return true; 
    return field1.toString() === field2; 
}; 

ou

$scope.filter2 = function(field1, field2) { 
    if(field2 === "" || field2 === null) return true; 
    return ""+field1 === field2; 
}; 
1

je suis tombé sur ce problème lorsque je charge une configuration de forme de JSON et les numéros ont été passés en auberge nombre accumulez pas.

<div ng-repeat="selectedComponent from ctrl.drivers.components | 
    filter:{ 
      manufacturer: component.manufacturer, 
      type: component.type}:true"> 

Quand j'ai eu un type de composant de 1 et 10 fois apparaîtraient dans mon ng répétition avant ajouté le :true à mon filtre, et rien quand j'avais ajouté une stricte égalité.

Pour résoudre ce problème, j'ai ajouté une méthode pour mon contrôleur appelé castToInt

ctrl.castToInt = function(value){ 
    return parseInt(value); 
}; 

Alors je modifié mon filtre pour afficher

<div ng-repeat="selectedComponent from ctrl.drivers.components | 
    filter:{ 
      manufacturer: component.manufacturer, 
      type: ctrl.castToInt(component.type)}:true"> 

Voila alors tout travaillé

Je pense que :true applique l'égalité stricte === de sorte que vous obtiendrez un faux si vous comparez différents types.

Si vous pouvez accepter de changer le type de votre valeur, alors la réponse acceptée est suffisante, mais si vous n'avez aucun contrôle sur les données qui vous sont présentées, cette méthode fonctionne.

-. Thomas

0

Si vous souhaitez effectuer une recherche par nom, par exemple ajouter simplement une zone de texte avec le nom = search.yourFieldNameToName, si vous voulez rechercher dans tous les domaines il suffit de créer une zone de texte avec la recherche $ et il suffit d'ajouter un filtre: recherche: strict sur votre directive ng-repeat.

Exemple de code Pour mieux expliquer:

<div class="customers view"> 
<div class="container"> 
    <header> 
     <h3>Customers</h3> 
    </header> 
    <div class="row"> 
     <div class="span3"> 
      Search All: 
      <input data-ng-model="search.$" type="text" placeholder="All Search" /> 
     </div> 
     <div class="span3"> 
      Search By Name: 
      <input data-ng-model="search.firstName" type="text" placeholder="First Name Search" /> 
     </div> 
     <div class="span3"> 
      Search By LastName: 
      <input data-ng-model="search.lastName" type="text" placeholder="Last Name Search" />     
     </div> 
     <div class="span3"> 
      Search By City: 
      <input data-ng-model="search.city" type="text" placeholder="City Search" /> 
     </div> 

    </div> 
    <div> 
     <div class="row cardContainer"> 
      <div class="span3 card" data-ng-repeat="customer in customers | filter:search:strict | orderBy:'firstName'"> 
       <button class="btn close cardClose" data-ng-click="deleteCustomer(customer.id)">&times;</button> 
       <div class="cardHeader">{{customer.firstName + ' ' + customer.lastName}}</div> 
       <div class="cardBody">{{customer.city}}</div> 
       <a href="#/customerorders/{{customer.id}}" class="cardBody btn-link">View {{ customer.orders.length }} Orders</a> 
      </div> 
     </div> 
    </div> 
</div> 

Questions connexes