Angular: 为什么延迟加载装饰器不起作用?

Angular: Why lazy-loading a decorator doesn't work?

Synchronously registering a decorator

angular
  .module('myApp')
  .decorator('$controller', MyDecorator);

angular
  .module('myApp')
  .controller('MyCtrl', MyCtrl);

Asynchronously registering a decorator

$timeout(function () {
  angular
    .module('myApp')
    .register
    .decorator('$controller', MyDecorator);

  // Make sure controller is registered after decorator
  $timeout(function () {
    angular
      .module('myApp')
      .register
      .controller('MyCtrl', MyCtrl);
  }, 1000);
}, 1000);

为什么第二个示例不起作用?

如您所知,AngularJS 在 bootstrap 期间有 2 个不同的阶段:

  1. 配置阶段
  2. 运行相

来自official documentation

A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consists of a collection of two kinds of blocks:

  1. Configuration blocks - get executed during the provider registrations and configuration phase. Only providers and constants can be injected into configuration blocks. This is to prevent accidental instantiation of services before they have been fully configured.
  2. Run blocks - get executed after the injector is created and are used to kickstart the application. Only instances and constants can be injected into run blocks. This is to prevent further system configuration during application run time.

在上面的引用中,我突出显示了关于 运行 块:

的句子

This is to prevent further system configuration during application run time

现在,在 AngularJS documentation about decorator:

Like with $provide.decorator, the module.decorator function runs during the config phase of the app. That means you can define a module.decorator before the decorated service is defined.

所以控制器(或服务或过滤器)的装饰是在配置阶段而不是在运行阶段[=41]完成的=].

因此,您的 "asynchronously registering a decorator" 示例不起作用:您正试图在 initCtrl 函数内定义和修饰控制器。但是后者在运行阶段被调用,在这个阶段定义新的装饰器已经太迟了。