如何有条件地向 ng-repeat inside 指令添加过滤器?

How do I conditionally add a filter to ng-repeat inside directive?

我在多个视图上使用元素指令。该指令对资源列表中的每个 'resource' 重复,就像这样:ng-repeat="resource in resources".

不同的页面控制器将通过在每个视图控制器中使用不同的 $scope.resourceApiPath 来确定将从 API 中提取哪些资源,然后指令控制器使用它来进行 $http 调用.

这适用于显示不同资源的不同视图。例如一个视图显示用户自己的所有资源,一个视图显示public个资源,一个视图显示用户已加星标的资源等。

唯一的问题是,对于我的一个观点,我想在 ng-repeat 上添加一个过滤器,如下所示:ng-repeat="resource in resources | filter:resourceSearch.text"。有没有办法根据条件添加此过滤器,例如如果 $scope.filter == true;,否则简单地返回常规 ng-repeat="resource in resources"?

这是我的指令:

.directive('resourcePanel', function() {
    return {
        restrict: 'E',
        scope: false,
        templateUrl: 'scripts/templates/resource-panel.html',
        controller: 'ResourcesPanelController'
    }
})

指令中引用的ResourcesPanelController是这样的:

$scope.resources = [];
$scope.loadResources = function() {
    $scope.resources = []; // Empty the array
    $http.get('/api/resource' + $scope.resourceApiPath)
        .then(function(res) {
            $scope.resources = res.data.message;
        });
};
$scope.loadResources();

scripts/templates/resource-panel.html 元素模板如下所示:

<div class="panel" ng-repeat="resource in resources">
    {{resource.content}}
</div>

谢谢!

<div ng-if="!filter" class="panel" ng-repeat="resource in resources">
    {{resource.content}}
</div>
<div ng-if="filter" class="panel" ng-repeat="resource in resources| filter:resourceSearch.text">
    {{resource.content}}
</div>

抱歉没有描述,如果我很确定它只出现一次,我有时会使用它,因为当你把它弄平时..

<div ng-if="!filter" class="panel" ng-repeat="resource in resources">{{resource.content}}</div>
<div ng-if="filter" class="panel" ng-repeat="resource in resources|filter:resourceSearch.text">{{resource.content}}</div>

那看起来真的没那么糟糕。

但更完整的解决方案是设置自定义过滤器并注入 'filter'

app.filter('conditionalFilter', function (filter) {
  return function (item, condition) {
    if(condition){
       return filter.bind(this,item).apply(this,[].slice.call(arguments,2));
    } else{ return item }
  };
});

然后

<div class="panel" ng-repeat="resource in resources| conditionalfilter : !!filter : researchSearch.text" >
    {{resource.content}}
</div>

没有测试过,如有错误请告知。

我认为您可以采用四种方式之一,我更喜欢 1 和 3,但这完全取决于您的要求和代码标准,哪一种最适合您。

自定义过滤器也是一个干净的解决方案。

  1. 如果您使用文本值作为筛选器,那么如果您不设置 resourceSearch.text 的值,那么它就像没有筛选器一样好,所以如果 resourceSearch.text 存在它会过滤,如果它未定义则没有过滤器。

    ng-重复="resource in resources | filter:resourceSearch.text"

  2. 创建自定义过滤器并在那里处理它。

如果你想创建一个自定义过滤器,然后使用启用参数,你可以使用它来打开和关闭你的过滤器http://plnkr.co/edit/ilPJPUZkBC7Y5OvGHWey?p=preview我已经找到了一个 plunkr 以及适合你需要的自定义过滤器

ng-repeat="resource in resources | customfilter:resourceSearch.text:enable"
  1. 在控制器中过滤您的最终资源并将过滤后的值传递给html

  2. 将 ng-if 与您的条件一起使用,如果存在过滤器,则使用一个循环,如果不存在,则使用不同的循环。

希望对您有所帮助。

您可以使用自定义过滤功能:

$scope.conditionalFilter = function(resource) {
    if (!$scope.filter) {
        return true;
    }

    // normal filter logic goes here, e.g.
    return resource.content.indexOf($scope.resourceSearch.text) >= 0;
};

然后在您的模板中使用自定义过滤器:

<div class="panel" ng-repeat="resource in resources | filter:conditionalFilter">
    {{resource.content}}
</div>