Spec-Zone.ru › Angular.js 1.5

Улучшить эту документациюДекораторы в AngularJS

ПРИМЕЧАНИЕ: Это руководство предназначено для разработчиков, уже знакомых с основами AngularJS. Если вы только начинаете, рекомендуем начать с руководства по началу работы.

Что такое декораторы?

Декораторы — это паттерн проектирования, используемый для разделения модификации или декорирования класса без изменения исходного кода. В Angular декораторы — это функции, которые позволяют модифицировать сервис, директиву или фильтр перед их использованием.

Как использовать декораторы

Существует два способа регистрации декораторов

  • $provide.decorator, и
  • module.decorator

Каждый предоставляет доступ к $delegate, который является экземпляром сервиса/директивы/фильтра, прежде чем он будет передан сервису, который его запросил.

$provide.decorator

Функция декоратора позволяет получить доступ к $delegate сервиса после его создания. Например:

angular.module('myApp', [])

.config([ '$provide', function($provide) {

  $provide.decorator('$log', [
    '$delegate',
    function $logDecorator($delegate) {

      var originalWarn = $delegate.warn;
      $delegate.warn = function decoratedWarn(msg) {
        msg = 'Decorated Warn: ' + msg;
        originalWarn.apply($delegate, arguments);
      };

      return $delegate;
    }
  ]);
}]);

После создания сервиса $log срабатывает декоратор. Функция декоратора получает объект $delegate для доступа к сервису, соответствующему селектору в декораторе. Этот $delegate будет сервисом, который вы декорируете. Значение, возвращаемое функцией переданной декоратору, заменит декорируемый сервис, директиву или фильтр.

Этот $delegate может быть изменён или полностью заменён. Учитывая сервис myService с методом someFn, следующие решения могут быть приемлемыми:

Полная замена $delegate

angular.module('myApp', [])

.config([ '$provide', function($provide) {

  $provide.decorator('myService', [
    '$delegate',
    function myServiceDecorator($delegate) {

      var myDecoratedService = {
        // new service object to replace myService
      };
      return myDecoratedService;
    }
  ]);
}]);

Модификация $delegate

angular.module('myApp', [])

.config([ '$provide', function($provide) {

  $provide.decorator('myService', [
    '$delegate',
    function myServiceDecorator($delegate) {

      var someFn = $delegate.someFn;

      function aNewFn() {
        // new service function
        someFn.apply($delegate, arguments);
      }

      $delegate.someFn = aNewFn;
      return $delegate;
    }
  ]);
}]);

Расширение $delegate

angular.module('myApp', [])

.config([ '$provide', function($provide) {

  $provide.decorator('myService', [
    '$delegate',
    function myServiceDecorator($delegate) {

      function helperFn() {
        // an additional fn to add to the service
      }

      $delegate.aHelpfulAddition = helperFn;
      return $delegate;
    }
  ]);
}]);
Обратите внимание, что всё, что возвращает функция декоратора, заменит декорируемый элемент. Например, отсутствие оператора return уничтожит весь декорируемый объект.

Декораторы имеют разные правила для разных сервисов. Это связано с тем, что сервисы регистрируются по-разному. Сервисы выбираются по имени, однако фильтры и директивы выбираются путём добавления "Filter" или "Directive" в конец имени. Предоставляемый $delegate определяется типом сервиса.

Тип сервиса Селектор $delegate
Сервис serviceName Значение, возвращаемое сервисом или function
Директива directiveName + 'Directive' Объект Array.<DirectiveObject>1
Фильтр filterName + 'Filter' Значение, возвращаемое фильтром function

1. Несколько директив могут быть зарегистрированы для одного селектора/имени

ПРИМЕЧАНИЕ: Разработчики должны тщательно обдумать способ и причину модификации $delegate сервиса. Необходимо учитывать ожидания потребителя, а также то, что некоторые функции (например, регистрация директив) не выполняются после декорации, а во время создания/регистрации исходного сервиса. Это означает, что, например, действие по добавлению объекта директивы в массив директивы $delegate может привести к непредсказуемому поведению. Кроме того, следует проявлять крайнюю осторожность при декорировании основных сервисов, директив или фильтров, поскольку это может непредвиденно или негативно повлиять на функциональность фреймворка.

module.decorator

Эта функция такая же, как функция $provide.decorator , но доступна через API модуля. Это позволяет изолировать ваши паттерны декораторов от блоков конфигурации модуля. Главное замечание здесь состоит в том, что вам нужно обратить внимание на порядок создания ваших декораторов.

В отличие от блока конфигурации модуля (который позволяет конфигурировать сервисы до их создания), сервис должен быть зарегистрирован до декоратора (см. Рецепт провайдера). Например, следующее не будет работать, потому что вы пытаетесь декорировать вне фазы конфигурации, и сервис ещё не был создан:

// will cause an error since 'someService' hasn't been registered
angular.module('myApp').decorator('someService', ...);

angular.module('myApp').factory('someService', ...);

Примеры применения

В следующих разделах представлены примеры декораторов сервиса, директивы и фильтра.

Этот пример показывает, как мы можем заменить сервис $log своим собственным для отображения сообщений об ошибках.

Пропущенные интерполированные выражения в атрибутах ng-href могут легко остаться незамеченными. Мы можем декорировать ngHref , чтобы предупреждать нас об этих ситуациях.

Предположим, мы создали приложение, которое использует стандартный формат для многих наших Date фильтров. Внезапно требования изменились (что в жизни редко случается), и нам нужно, чтобы все наши даты по умолчанию были в формате 'shortDate' вместо 'mediumDate'.

© 2010–2017 Google, Inc.
Licensed under the Creative Commons Attribution License 4.0.
https://code.angularjs.org/1.5.11/docs/guide/decorators

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API