How to pass filter to a directive in AngularJS

五迷三道 提交于 2020-01-11 11:28:10

问题


I have a custom directive and I want to be able to pass a filter name to it. That filter will then be use in my template. Here is what I got so far:

the directive:

angular.module('forecastDirective', [])
.directive('forecast', ['appConfig', function(appConfig) {
    return {
        templateUrl: appConfig.directivesRoot + 'templates/forecast.html',
        replace: true,
        scope: {
            weatherObject: "=",
            convertToDate: "&",
            filterTemp: "@",
            dateFormat: "@",
        },
    }
}]);

The template:

<div class="panel panel-default">
    <div class="panel-heading">
        <h3 class="panel-title">{{ convertToDate({ dt: weatherObject.dt }) | date: dateFormat }}</h3>
    </div>
    <div class="panel-body">
        Daytime temperature: {{ weatherObject.temp.day | filterTemp }}
    </div>
</div>

回答1:


A very simple way is, using the $filter service and a function in the scope that delegates to the correct filter:

angular.module('forecastDirective', [])
.directive('forecast', ['appConfig', function(appConfig) {
    return {
        templateUrl: appConfig.directivesRoot + 'templates/forecast.html',
        replace: true,
        scope: {
            weatherObject: "=",
            convertToDate: "&",
            filterTemp: "@",
            dateFormat: "@",
        },
        controller: ['$filter', '$scope', function($filter, $scope) {
            $scope.filterFn = function(in) {
                return $filter($scope.filterTemp)(in);
            };
        }
    }
}]);

A downside is that you can no longer use it as a filter:

    <div class="panel-body">
        Daytime temperature: {{ filterFn(weatherObject.temp.day) }}
    </div>

I guess the intended filter function returns a primitive (string, number, boolean). If it returns something complex (object, array), you may need to cache return values to avoid infinite digest cycles.


You can implement a meta-filter:

angular.module(...)
    .filter('metafilter', ['$filter', function($filter) {
        return function(input, filterName) {
            return $filter(filterName)(input);
        };
    }]);

Use it as:

    <div class="panel-body">
        Daytime temperature: {{ weatherObject.temp.day | metafilter:filterTemp }}
    </div>

This is a fiddle demonstrating the metafilter: https://jsfiddle.net/opL1zfzd/




回答2:


You don't need to have access to it in the controller to use it in the View. That's kind of the point of filters. If you actually needed it in the controller, you could request it by itself by asking for filterTempFilter to be injected. Or you can have the $filter provider injected and ask for your specific filter from it.



来源:https://stackoverflow.com/questions/34905351/how-to-pass-filter-to-a-directive-in-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!