1

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

我在研究期间从各种来源(包括官方文档,以及 Angular Guru 和传道者)知道,该$onInit块通常保留用于依赖于 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);
  }
}

虽然这看起来很适合遵循“角度方式”做事,仅使用$onInit块进行初始化工作/逻辑,我也看到很多人说角度控制器类构造函数应该只用于依赖注入设置

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

4

2 回答 2

2

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

$onInit用于 DOM 和数据绑定初始化代码,它是 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无法轻松访问控制器,因为无法导入控制器构造函数。

于 2017-08-03T15:55:30.480 回答
1

我同意你的一般评价。我的构造函数很轻,但是如果我在实例化时做的事情与角度无关,我一直在将它们放入构造函数中。我和他们没有任何问题。我只看了十几个左右,除了初始化属性并将依赖注入分配给属性之外,我基本上什么也没做。我只有一个控制器,它可以调用任何外部代码。

关于 Angular 1.5 的文章非常少。如果您还没有看过这个:https : //toddmotto.com/rewriting-angular-styleguide-angular-2 我认为这是“现代 angularjs”的最佳风格指南。

于 2017-08-03T16:02:25.040 回答