Angularjs - Декорирование контроллеров
Я пытаюсь настроить декоратор для моих контроллеров. Мое намерение состоит в том, чтобы ввести некоторое общее поведение для всех контроллеров в моем приложении.
Я настроил его на работу в Angular 1.2.x, но есть некоторые критические изменения, начиная с версии 1.3.x, которые нарушают код. Теперь появляется ошибка "контроллер не является функцией".
Ниже приведен код для декоратора:
angular.module('myApp', ['ng'], function($provide) {
$provide.decorator('$controller', function($delegate) {
return function(constructor, locals) {
//Custom behaviour code
return $delegate(constructor, locals);
}
})
});
Angular 1.2.x - http://jsfiddle.net/3v17w364/2/ (работает)
Angular 1.4.x - http://jsfiddle.net/tncquyxo/2/ (сломано)
2 ответа
В модулях Angular 1.4.x есть метод декоратора, $provide.decorator
больше не нужен.
Для API-приложений для исправления обезьян всегда предпочтительнее использовать arguments
вместо того, чтобы перечислять их явно, вероятность того, что он сломается, намного меньше.
angular.module('myApp', ['ng']).decorator('$controller', function ($delegate) {
return function (constructor, locals) {
var controller = $delegate.apply(null, arguments);
return angular.extend(function () {
locals.$scope.common = ...;
return controller();
}, controller);
};
});
Отвечая на мой собственный вопрос.
Пришлось копаться в исходном коде Angular, чтобы выяснить, что происходит.
Экземпляр $controller создается с использованием приведенного ниже кода. Исправление лежало в параметре "позже". Это должно быть установлено в true.
return function(expression, locals, later, ident) {
// PRIVATE API:
// param `later` --- indicates that the controller's constructor is invoked at a later time.
// If true, $controller will allocate the object with the correct
// prototype chain, but will not invoke the controller until a returned
// callback is invoked.
Выше взято из: https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js
Обновлен код провайдера:
angular.module('myApp', ['ng'], function($provide) {
$provide.decorator('$controller', function($delegate) {
return function(constructor, locals) {
//Custom behaviour code
return $delegate(constructor, locals, true);
}
})
});
Обновленная скрипка: http://jsfiddle.net/v3067u98/1/