NG1:Class 控制器构造函数与 $onInit 用于变量初始化和方法绑定

NG1: Class controller constructor vs $onInit for variable initialization and method bindings

在将此问题标记为重复之前...我知道您在想什么,这个问题已被问过无数次,但不完全是。

我在研究期间从各种来源(包括官方文档,以及 Angular 大师和布道者)得知 $onInit 块通常保留用于 初始化 work/logic 依赖于 angular 完成所有绑定.

然而,变量初始化并不真正符合这个 "work/logic" 定义。特别是其中没有任何 angular 逻辑的变量。因此,ES6 构造函数似乎更适合变量初始化。这同样适用于需要词法绑定回调范围的方法绑定,如下所示:

class myController() {
  constructor() {
    this.myVariableOne = 1,
    this.myVariableTwo = 2,
    this.myVariableThree = 3;

    this.myMethod = this.myMethod.bind(this);
  }

  $onInit() { }

  myMethod() {
    console.log(this.myVariableOne, this.myVariableTwo, this.myVariableThree);
  }
}

虽然这看起来很好地遵循 "the angular way" 的做事,只要使用 $onInit 块进行初始化 work/logic,我也看到很多人说angular 控制器 class 构造函数 应该只用于依赖注入设置 .

所以,这让我很困惑。构造函数似乎是最适合变量初始化和方法绑定的块,而 $onInit 似乎并不适合这个角色,但我真的不清楚我应该使用什么。有人可以帮我弄清楚我应该把我的变量定义和方法绑定放在哪里吗?

这完全取决于这些属性是什么。对于初始静态值(如上面的代码),构造函数是合适的地方。

$onInit 用于 DOM 和数据绑定初始化代码,它是 pre-1.5 pre-link 函数的直接对应物。出于可测试性原因,其他初始化代码也可以放在 $onInit 中。

考虑到初始化时调用了一些实例(非原型)方法:

constructor() {
  this.method = () => ...;
}

$onInit() {
  this.method();
}

可以这样测试

const ctrl = $controller('...');
spyOn(ctrl, 'method').and...;
ctrl.$onInit();
expect(ctrl.method).toHaveBeenCalled();

如果在构造函数中调用它,就不可能监视或模拟它。

这种担忧在更大程度上影响了非模块化 ES5 应用程序,因为它们的方法通常定义为 this.method = ...,并且无法轻松访问控制器 prototype,因为无法导入控制器构造函数。

我同意你的总体评价。我让我的构造函数非常轻巧,但如果我在实例化时做的事情实际上与 angular 无关,我一直将它们放入构造函数中。我对他们没有任何问题。我只看了其中的十几个,除了初始化属性和为属性分配依赖注入外,我基本上什么都没做。我只有一个控制器,它可以调用任何外部代码。

关于 angular 1.5 的文章很少。如果您还没有看过这个:https://toddmotto.com/rewriting-angular-styleguide-angular-2 我认为这是 "modern angularjs."

最好的风格指南