web-dev-qa-db-ja.com

1つのフィールドのみに対するAngularJSの厳密なフィルター

複数のフィルターを備えたフォームがありますが、厳密な比較が必要なものもあります。

tl; drfirstnameではなくuser_idの厳密な比較。

<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>

3番目のパラメーターtrueを試しましたが、firstnameフィルターでも機能します。

問題は、値2を選択すると、IDに2が含まれるすべてのユーザーがフィルタリングされるため、この動作は望ましくないということです。

これが fiddle です。

12
Syl

カスタムフィルターではなく、ネイティブに修正しようとしましたが、機能します PLUNKER LINK

複数のフィルタータグを指定する必要がありました

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

注意点はほとんどありませんが、

  1. タイプを数字から文字列に変更する必要がありました...

  2. 完全一致の値をリセットすると機能しません...

そのため、完全一致で機能し、空/ヌル値を無視するカスタムファイラーを作成する必要がありました

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

あなたはそれらの両方を提供されたプランカーリンクで見つけるでしょう

15
harishr

Jsonからフォーム構成をロードし、数値が文字列ではなく数値としてインに渡されたときに、この問題が発生しました。

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

コンポーネントタイプが1と10の場合、フィルターに:trueを追加する前に、両方がng-repeatに表示され、厳密な等式を追加した場合は何も表示されませんでした。

これを修正するために、castToIntというメソッドをコントローラーに追加しました

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

次に、フィルターを変更して表示します

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

出来上がり、それですべてうまくいきました

私の推測では、:trueは厳密な等式===を強制するため、異なるタイプを比較するとfalseが発生します。

値のタイプの変更を受け入れることができる場合は、受け入れられた回答で十分ですが、提示されるデータを制御できない場合は、この方法が機能します。

-トーマス

1
tFlolo

他の人の答えにはコメントできないので、このようにします。

HarisRのソリューションを使用しましたが、数値としての値が必要な場合にも数値で使用できるように変更しました。

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

または

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

あなたはあなたのコントローラーでこのような機能を持つことができます

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

そして、あなたはそれをこのように使うことができます

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

HTMLの変更:

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

両方の値が存在する場合、andが必要だと思います。必要に応じて、orに変更してください。カスタムフィルター機能:

$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;
};

コントローラへのもう1つの変更:

$scope.search= {};

フォークフィドル

0
Andy Gaskell

たとえば、名前で検索する場合は、name = search.yourFieldNameToNameのテキストボックスを追加します。すべてのフィールドで検索する場合は、search。$のテキストボックスを作成してから、ng-repeatにfilter:search:strictを追加します。指令。

サンプルコードよりよく説明するには:

<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>