如何有条件地向 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,但这完全取决于您的要求和代码标准,哪一种最适合您。
自定义过滤器也是一个干净的解决方案。
如果您使用文本值作为筛选器,那么如果您不设置 resourceSearch.text 的值,那么它就像没有筛选器一样好,所以如果 resourceSearch.text 存在它会过滤,如果它未定义则没有过滤器。
ng-重复="resource in resources | filter:resourceSearch.text"
创建自定义过滤器并在那里处理它。
如果你想创建一个自定义过滤器,然后使用启用参数,你可以使用它来打开和关闭你的过滤器http://plnkr.co/edit/ilPJPUZkBC7Y5OvGHWey?p=preview我已经找到了一个 plunkr 以及适合你需要的自定义过滤器
ng-repeat="resource in resources | customfilter:resourceSearch.text:enable"
在控制器中过滤您的最终资源并将过滤后的值传递给html
将 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>
我在多个视图上使用元素指令。该指令对资源列表中的每个 '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,但这完全取决于您的要求和代码标准,哪一种最适合您。
自定义过滤器也是一个干净的解决方案。
如果您使用文本值作为筛选器,那么如果您不设置 resourceSearch.text 的值,那么它就像没有筛选器一样好,所以如果 resourceSearch.text 存在它会过滤,如果它未定义则没有过滤器。
ng-重复="resource in resources | filter:resourceSearch.text"
创建自定义过滤器并在那里处理它。
如果你想创建一个自定义过滤器,然后使用启用参数,你可以使用它来打开和关闭你的过滤器http://plnkr.co/edit/ilPJPUZkBC7Y5OvGHWey?p=preview我已经找到了一个 plunkr 以及适合你需要的自定义过滤器
ng-repeat="resource in resources | customfilter:resourceSearch.text:enable"
在控制器中过滤您的最终资源并将过滤后的值传递给html
将 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>