Angularjs - Decorate Controllers

梦想与她 提交于 2019-11-29 21:35:28

问题


I am trying to set up a decorator for my controllers. My intention is to introduce some common behaviour across all the controllers in my app.

I have it configured to work in Angular 1.2.x, but there are some breaking changes from 1.3.x onwards that is breaking the code. The error one now gets is "controller is not a function".

Below is the code for the decorator:

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/ (Working)
Angular 1.4.x - http://jsfiddle.net/tncquyxo/2/ (Broken)


回答1:


In Angular 1.4.x modules have decorator method, $provide.decorator is no longer needed.

For monkey-patching APIs it is always preferable to use arguments instead of enumerating them explicitly, the chance that it will break is much lesser.

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);
    };
});



回答2:


Answering my own question.

Had to dig in to Angular source code to figure out whats going on.

The $controller instance is created using below code. The fix lay in the parameter 'later'. This needs to be set to 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.

Above taken from: https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.js

Updated provider code:

angular.module('myApp', ['ng'], function($provide) {
    $provide.decorator('$controller', function($delegate) {

 return function(constructor, locals) {

            //Custom behaviour code

            return $delegate(constructor, locals, true);
        }
    })
});

Updated fiddle: http://jsfiddle.net/v3067u98/1/



来源:https://stackoverflow.com/questions/32442605/angularjs-decorate-controllers

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