Передача фильтра в директиву с контроллера angularjs [дубликат]

Вы можете использовать регулярные выражения с динамическим шаблоном.

var text = "something";
var output = "                    ";
var pattern = new RegExp("^\\s{"+text.length+"}");
var output.replace(pattern,text);

выходы:

"something      "

Это заменяет text.length пробельных символов в начале строки output. RegExp означает ^\ - начало строки \s любого символа пробела, повторение {n} раз, в данном случае text.length. Используйте \\ к \, чтобы избежать обратных косых черт при построении таких шаблонов из строк.

1
задан Kévin Duguay 20 January 2016 в 17:28
поделиться

2 ответа

Очень простой способ - использовать службу $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);
            };
        }
    }
}]);

Недостатком является то, что вы больше не можете использовать его как filter:

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

Предполагаю, что функция фильтра возвращает примитив (строка, число, логическое значение). Если он возвращает что-то сложное (объект, массив), вам может потребоваться кэшировать возвращаемые значения, чтобы избежать бесконечных циклов дайджеста.


Вы можете реализовать мета-фильтр:

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

Используйте его как:

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

Это скрипка, демонстрирующая метафильтр: https://jsfiddle.net/opL1zfzd/

1
ответ дан Nikos Paraskevopoulos 20 August 2018 в 17:33
поделиться
  • 1
    Я знаю, что могу использовать функцию, но все равно я могу просто передать фильтр, который я хочу, или это невозможно? – Kévin Duguay 20 January 2016 в 17:46
  • 2
    Вы можете сделать это, манипулируя шаблоном в функции compile. Вы не хотите этого делать. Вы также можете скомпилировать фрагмент HTML, содержащий имя фильтра. Вы не хотите, чтобы это было (слишком сложно без причины). Я не знаю другого способа структурного динамического изменения шаблона. С другой стороны, вы можете реализовать мета-фильтр, который делает то, что делает filterFn выше, но в упаковке фильтра. Я уточню вопрос, если он будет полезен. – Nikos Paraskevopoulos 20 January 2016 в 17:50

Вам не нужно иметь доступ к нему в контроллере, чтобы использовать его в представлении. Это своего рода точка фильтров. Если вы действительно нуждались в нем в контроллере, вы можете запросить его самостоятельно, попросив ввести filterTempFilter. Или вы можете ввести провайдера $ filter и запросить у него свой фильтр.

1
ответ дан Amy Blankenship 20 August 2018 в 17:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: