【问题标题】:Making an angular filter conditional使角度过滤器有条件
【发布时间】:2015-06-26 14:17:59
【问题描述】:

我目前正在使用文本输入来过滤项目列表。我想这样做,所以当设置特定变量时,无论文本输入是什么,列表都不会过滤。关于如何实现这一点的任何建议?

<a ng-repeat="set in data | filter: { value: search }" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>

【问题讨论】:

标签: angularjs


【解决方案1】:

在 HTML 模板绑定中

{{ dataX | date: expression ? 'dd/MM' : 'dd/MM/yyyy' }}

【讨论】:

    【解决方案2】:

    如果您将过滤器表达式设置为''(或undefined),则可以实现此目的 - 这会导致不应用过滤器 - 当您设置了 disableFilter 时,否则设置为实际的过滤器表达式。

    编辑 2: 另一个答案(下面是@Ryan)更简单、更容易理解。现在不记得是它最初对我不起作用还是我根本没有想到这种更简单的方法。

    所以,假设这个切换变量 - disableFilter - 是一个布尔值:

    <a ng-repeat="set in data | filter: (!disableFilter || '') && filterExpression">
    

    filterExpression 是您想要过滤的任何表达式)。您的具体情况是:

    <a ng-repeat="set in data | filter: (!disableFilter || '') && {value: search}">
    

    编辑:

    解释上面的工作原理。

    1. 请记住,||&amp;&amp; 返回其操作数之一的值。
    2. ||&amp;&amp; 使用短路评估 - true || (anything) 返回 truefalse &amp;&amp; (anything) 返回 false - 不计算 (anything) 表达式。
    3. '' 是假的(或者使用 undefined 代替,如果它更清楚)

    所以,

    disableFilter === true!disableFilter === false 时,|| 的第二个操作数 - 空字符串 '' - 被求值(它是假的),并且 (!disableFilter || '') 返回 '' - 一个假值,短- 循环&amp;&amp; 操作并且不计算&amp;&amp; 的第二个操作数。因此表达式的返回值为''

    disableFilter === false!disableFilter === true 使|| 操作短路时,则评估并返回&amp;&amp; 的第二个操作数。因此表达式的返回值为{value: search}

    阅读更多关于logical operators here

    【讨论】:

    • 太棒了!这就是我想做的事情!但我不是很明白,希望你能解释一下。这不是说disableFilter 是假字符串还是空字符串?我不明白这如何等同。
    • 太棒了!我完全忽略了在 JS 中,非布尔值之间的逻辑仍然像你所说的那样评估为真或假。我认为空字符串,虚假,是让我失望的原因。
    • 不确定我做错了什么,但它对我不起作用。当!disableFilter 为真时,我的过滤器会清除列表中的所有项目。我假设我可以将scope.myFilterText 作为{ value: myFilterText } 中的值传递?
    • @chovy,如果您删除了(!disableFilter || '') 部分,它会正确过滤吗?
    • 刚刚找到方法:filter : (doFilter?{value:search}:'') :(doFilter?true:false)
    【解决方案3】:

    我发现以下解决方案更简单有效

    angular.module('myApp', []).controller('namesCtrl', function($scope) {
        $scope.package=[{"PkgServiceId":null,"PkgServicesName":" HB, TLC, DLC &amp; ESR, EDTA WHOLE BLOOD, HBSAG CONFIRMATION,SERUM, Blood Cholesterol","PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":108,"ServiceName":"Family Health Package"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":70,"ServiceName":"HB, TLC, DLC & ESR, EDTA WHOLE BLOOD"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":71,"ServiceName":"HBSAG CONFIRMATION,SERUM"},{"PkgServiceId":108,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":3,"ServiceDesc":"Its used to evaluate your overall health and detect a wide range of disorders","ServiceId":2,"ServiceName":"Blood Cholesterol"},{"PkgServiceId":null,"PkgServicesName":" MRI Test, HB, TLC &amp; DLC, EDTA WHOLE BLOOD","PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":107,"ServiceName":"Child Health Package"},{"PkgServiceId":107,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":"Its used to evaluate your overall health and detect a wide range of disorders","ServiceId":5,"ServiceName":"MRI Test"},{"PkgServiceId":107,"PkgServicesName":null,"PromoDiscount":null,"PromoID":null,"ReportPeriod":5,"ServiceDesc":null,"ServiceId":69,"ServiceName":"HB, TLC & DLC, EDTA WHOLE BLOOD"}] ;
    });
    <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <body>
    
    <div ng-app="myApp" ng-controller="namesCtrl">
    <ul>
          <li ng-repeat="x in package">
            {{ x.ServiceName }}
            
          </li>
        </ul>
    <p>Above is the total data set without filtering.</p>
    <ul>
      <li ng-repeat="x in package| filter :{PkgServiceId: null}">
        {{ x.ServiceName }}
        {{ x.PkgServiceId }}
        
      </li>
    </ul>
    
    </div>
    
    
    
    <p>This example displays only the packages containing the packageId "null".</p>
    
    </body>
    </html>

    【讨论】:

      【解决方案4】:

      我的案子很复杂

      • 有一个记录说它产品的列表
      • 按用户从下拉列表中选择的另外两个属性prop1prop2 进行过滤
      • 另一个下拉列表 (prop3) 有两个值 1 和 2,如果用户选择 2,则不应应用过滤器

      她的就是我的结果:

      ng-repeat="prod in filterdProd = 
       (products | filter : model.prop3 == 2 ? '' :  
         { 'prop1': model.prop1 || 'none', 
           'prop2': model.prop2 }) | 
        orderBy: 'productrName'"
      

      如果model.prop3 == 2 ? '' 过滤器将不适用,否则...

      我们也可以通过 filterdProd 来使用记录数

      【讨论】:

        【解决方案5】:

        我认为以下是一个稍微不那么棘手的解决方案。棘手的解决方案会给未来的开发人员带来错误。

        这是我的建议:

        <a ng-repeat="set in data | filter: (shouldFilter ? filterExpression : '')">
        

        <a ng-repeat="set in data | filter: (shouldFilter ? {value: search} : '')">
        

        简单地说,如果 shouldFilter,则给它你的过滤器表达式,否则什么也不给它。 使用简单的三元表达式会更容易阅读。

        【讨论】:

        • 非常简单易懂。谢谢!
        • 谢谢。绝对比我的方法更简单。
        【解决方案6】:

        这就是我所做的。首先,我有一个从我的控制器填充的选择控件,其中包含一个长度为零的字符串值的静态项(选择...):

        <select data-ng-model="districtFilter" class="form-control" data-ng-options="d.DistrictId as d.DistrictName for d in districts | orderBy: 'DistrictName'"><option value="">Select...</option></select>
        

        然后我有条件地在桌子上应用了过滤器。它在过滤器为空时出现,将其设置为 undefined 会清除它:

        <tr data-ng-repeat="courtEntity in courts | filter:{ 'DistrictId' : districtFilter === null ? undefined : districtFilter}">
        

        【讨论】:

        • 我只是使用三元作为 .
        【解决方案7】:

        制作函数并与filterExpression结合。

        例如我有一个学生列表如下:

        $scope.students = [  
           { name: 'Hai', age: 25, gender: 'boy' },  
           { name: 'Hai', age: 30, gender: 'girl' },  
           { name: 'Ho', age: 25, gender: 'boy' },  
           { name: 'Hoan', age: 40, gender: 'girl' },  
           { name: 'Hieu', age: 25, gender: 'boy' }  
         ];  
        

        我想通过性别过滤学生是男孩并按他们的名字过滤。

        首先我创建了一个名为“filterbyboy”的函数,如下所示:

        $scope.filterbyboy = function (genderstr) {  
           if ((typeof $scope.search === 'undefined')||($scope.search === ''))  
             return (genderstr = "")  
           else  
            return (genderstr = "boy");  
         };  
        

        说明:如果不过滤姓名,则显示所有学生,否则按输入姓名和性别过滤为“男孩”

        这是一个演示How to use and operator in AngularJs example

        【讨论】:

          【解决方案8】:

          也许使用ng-if

          <a ng-if="!myConditional" ng-repeat="set in data" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>
          <a ng-if="myConditional" ng-repeat="set in data | filter: { value: search }" data-id="{{set.id}}" ng-mousedown="setBox(set)" ng-mouseover="setSelected(set, $event)" ng-bind-html="set.value | trustHTML"></a>
          

          那似乎是solution

          【讨论】:

          • 可以,但是如果我们想知道数组的长度(无限滚动),我们不能... :/
          猜你喜欢
          • 2017-02-21
          • 2018-03-23
          • 1970-01-01
          • 2015-09-16
          • 1970-01-01
          • 2021-09-05
          • 2015-06-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多