我看到了各种版本的如何将依赖项注入到我的组件中,有些版本对我有用,有些则不然。所以我想知道,有什么优点和缺点,建议的最佳做法是什么,为什么某些不能按预期工作。这是一个例子:
@Component()
@Injectable()
class MyComponent {
dependency1: Dependency1;
constructor(dependency2: Dependency2, dependency3: Dependency3) {
this.dependency2 = dependency2;
}
someFunction() {
// Which of those will work, which is the best practice,
//what are pros and cons
this.dependency1.get();
this.dependency2.get();
this.dependency3.get();
}
}
所以基于这个例子:
版本1(Dependency1)是否等同于版本2(Dependeny2)?或者版本1仅适用于TypeScript而与注射没有任何关联?
这行代码是
this.dependency2 = dependency2;
必须做到这一点"自动化"喜欢假设为Dependency3?
非常感谢
答案 0 :(得分:3)
您似乎正在混合使用typescript 参数属性和Angular2 DI机制。
基本上,在使用typescript定义构造函数时,您有两个选项。简短版本:
@Component()
class MyComponent {
constructor(
public dependency1: Dependency1,
public dependency2: Dependency2,
public dependency3: Dependency3
) { }
// [...]
这将转换为您也可以使用的更长,更详细的版本:
@Component()
class MyComponent {
public dependency1: Dependency1;
public dependency2: Dependency2;
public dependency3: Dependency3;
constructor(
dependency1: Dependency1,
dependency2: Dependency2,
dependency3: Dependency3
) {
this.dependency1 = dependency1;
this.dependency2 = dependency2;
this.dependency3 = dependency3;
}
// [...]
Typescript Handbook对此进行了解释。 两者都有他们的专业人士缺点,较长的版本对于打字稿的新手来说更容易理解和清晰,而后者则节省了相当多的打字,所以选择你的毒药。 :)
注意:如果您的类已经有另一个装饰器,则不需要@Injectable()装饰器,它只用于通过typescript强制生成元数据,它只适用于装饰类用不必要的元数据防止膨胀的代码。
关于DI技工,假设您导入了定义以及Dependency1,Dependency2和Dependency3(1),注册了他们的提供者(2)和angular
创建了组件的实例(3):
内部someFunction()
this.dependency1
是一个声明的(在您班级的开头是公开的)并且具有针对所有打字关注的已定义类型(Dependency1
)。但是它的当前值是undefined
,因为它没有在构造函数(或其他任何地方)中赋值。
修复将dependency1: Dependency1
参数添加到构造函数并指定this.dependency1 = dependency1
或使用上面的typescript短文([编辑] {{1 }})。
在构造函数中访问constructor(public dependency1, ...
会引发编译错误,因为this.dependency2
没有属性MyComponent
。在不太可能的情况下,这会编译/转换,然后dependency2
应该具有正确的值,尽管您不会有this.dependency2
的类型信息(坏)。
修复:为您的组件添加this.dependency2
声明,例如。在构造函数[编辑]上方添加this.dependency2
,或在构造函数public dependency2: Dependency2;
参数public
)前面添加dependency2
属性。
最后但并非最不重要constructor(public dependency2, ...
有上述两个问题,没有声明(例如this.dependency3
)和dependency2
作为值(例如undefined
)。< / p>
修复:见上文。 ;)
注意:了解declaration & definition(这是关于C ++,但也适用于打字稿以及)之间的区别很重要,我希望在拍打时我没有混淆条款。 ;)
例如通过:
完成dependency1
有多种方法可以为依赖项定义提供程序
在bootrap期间。这使得模块(通过其提供者)可用于应用程序中的每个组件。
import { Dependency1 } from 'dependency-module-1';
import { Dependency2 } from 'dependency-module-2';
import { Dependency3 } from 'dependency-module-3';
使用组件装饰器。这使得模块可用于MyComponent,相同的模块实例可用于每个子组件。 如果子组件hovever具有自己的提供者数组,则会为其生成 new 模块实例(并且与所有子组件的 shared 一样)。推荐的阅读材料是official Angular2 guide和this博文。这是一个例子:
bootstrap(AppComponent, [
Dependency1,
Dependency2,
Dependency3
]);
MyComponent是为angulars bootstrap方法传递的(第一个)参数,或者在DOM中的某个地方使用组件选择器。
关于最佳做法,您可以尝试使用tslint和令人敬畏的custom-rule-plugins,例如。 codealyze one是特定于角度的。
最后但并非最不重要的还有官方的Angular Typescript Styleguide。 ;)
答案 1 :(得分:0)
请查看官方documentation
另请查看此blog
Angular基于constructor based dependency injection。
简而言之,这意味着构造函数参数作为依赖注入
Car(e:Engine)
然后引擎将在汽车实例中通过DI注入。
现在你的所有代码都是Typescript定义构造函数的方法。以下2个代码是等效的。
e: Engine
Car(e:Engine){
this.e = e
}
Car(public e:Engine){ }