AngularJS
Декораторы
Поиск…
Синтаксис
- декоратор (имя, декоратор);
замечания
Decorator - это функция, которая позволяет модифицировать сервис , фабрику , директиву или фильтр до его использования. Decorator используется для переопределения или изменения поведения сервиса. Возвращаемое значение функции декоратора может быть исходной услугой или новой службой, которая заменяет или обертывает и делегирует исходную услугу.
Любое украшение должно быть выполнено в фазе config
углового приложения, введя $provide
и используя функцию $provide.decorator
.
Функция декоратора имеет объект
$delegate
вводится для обеспечения доступа к службе, которая соответствует селектору в декораторе. Этот$delegate
будет сервисом, который вы украшаете. Возвращаемое значение функции, предоставляемой декоратору, будет иметь место при оформлении услуги, директивы или фильтра.
Следует рассмотреть использование декоратора только в том случае, если какой-либо другой подход не подходит или окажется слишком утомительным. Если большое приложение использует тот же сервис, а одна часть изменяет поведение службы, легко создать путаницу и / или ошибки в этом процессе.
Типичным вариантом использования будет тот факт, что у вас есть зависимая от третьей стороны, которую вы не можете обновить, но вам нужно немного поработать или расширить ее.
Украсить сервис, завод
Ниже приведен пример декоратора сервисов, переопределяющий null
дату, возвращаемую службой.
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myService', function($delegate) {
$delegate.getDate = function() { // override with actual date object
return new Date();
};
return $delegate;
});
})
.service('myService', function() {
this.getDate = function() {
return null; // w/o decoration we'll be returning null
};
})
.controller('myController', function(myService) {
var vm = this;
vm.date = myService.getDate();
});
<body ng-controller="myController as vm">
<div ng-bind="vm.date | date:'fullDate'"></div>
</body>
Указать директиву
Директивы могут быть оформлены так же, как и сервисы, и мы можем модифицировать или заменять любые его функциональные возможности. Обратите внимание, что сама директива доступна в позиции 0 в $ delegate array, а параметр name в декораторе должен содержать суффикс Directive
(с учетом регистра).
Итак, если директива называется myDate
, ее можно получить с помощью myDateDirective
используя $delegate[0]
.
Ниже приведен простой пример, когда директива показывает текущее время. Мы украсим его, чтобы обновить текущее время за одну секунду. Без украшения он всегда будет показывать одно и то же время.
<body>
<my-date></my-date>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myDateDirective', function($delegate, $interval) {
var directive = $delegate[0]; // access directive
directive.compile = function() { // modify compile fn
return function(scope) {
directive.link.apply(this, arguments);
$interval(function() {
scope.date = new Date(); // update date every second
}, 1000);
};
};
return $delegate;
});
})
.directive('myDate', function() {
return {
restrict: 'E',
template: '<span>Current time is {{ date | date:\'MM:ss\' }}</span>',
link: function(scope) {
scope.date = new Date(); // get current date
}
};
});
Украсить фильтр
При декорировании фильтров параметр имени должен включать в себя Filter
суффикс (с учетом регистра). Если фильтр называется repeat
, параметр декоратора - repeatFilter
. Ниже мы будем декорировать пользовательский фильтр, который повторяет любую заданную строку n раз, чтобы результат был обратным. Вы также можете украшать встроенные фильтры углов одинаково, хотя и не рекомендуется, так как это может повлиять на функциональность фреймворка.
<body>
<div ng-bind="'i can haz cheeseburger ' | repeat:2"></div>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('repeatFilter', function($delegate) {
return function reverse(input, count) {
// reverse repeated string
return ($delegate(input, count)).split('').reverse().join('');
};
});
})
.filter('repeat', function() {
return function(input, count) {
// repeat string n times
return (input || '').repeat(count || 1);
};
});