Angular的constructor与ngOnInit有什么区别?分别应放置什么代码?
Angular组件constructor与ngOnInit代码拆分说明
你现有代码的迁移建议
你当前写在constructor中的代码,除了this.environment = this.environmentService.get()(如果该方法是无副作用的同步配置读取)和简单变量初始化,其余都建议迁移到ngOnInit中,调整后代码参考如下:
export class SignUpComponent implements OnInit { environment: Environment; form: FormGroup; // 基础类型常量直接在属性声明时赋值即可,无需写在构造方法 stage = 1; constructor( private router: Router, private title: Title, private formBuilder: FormBuilder, private analyticsService: AnalyticsService, private environmentService: EnvironmentService) { // 仅保留无副作用的同步配置读取 this.environment = this.environmentService.get(); } ngOnInit() { this.title.setTitle('Registar - Bons Alunos'); this.analyticsService.pageview('Sign Up', this.router.url); this.form = this.formBuilder.group({ email: ['', [Validators.required, Validators.email]] }); } }
两类方法的使用规则
适合放在ngOnInit、不适合放在constructor的代码
Angular中constructor是TypeScript类的原生构造方法,执行时机非常早:此时组件的@Input输入参数、@ViewChild/@ContentChild引用的元素、绑定的DOM都还未完成初始化,仅完成了依赖注入的实例化。所以以下类型的代码必须放在ngOnInit中:
- 依赖
@Input输入参数的逻辑:比如要根据父组件传入的ID查询数据,constructor阶段完全拿不到输入参数的赋值 - 带有业务副作用的逻辑:包括接口请求、埋点上报、本地存储读写、页面标题修改等,这类逻辑放在constructor中不仅会提升组件实例化失败的概率,也会让单元测试难以编写
- 依赖DOM或组件生命周期状态的逻辑:比如表单初始化(后续如果要关联输入参数的默认值,放在ngOnInit不需要重构)、路由参数获取、DOM操作等
仅适合放在constructor的代码
constructor仅用来做两类操作:
- 接收注入的依赖实例,赋值给类属性
- 做无任何副作用的基础常量初始化
不要在constructor中写任何和业务逻辑、组件渲染相关的代码。
内容的提问来源于stack exchange,提问作者Miguel Moura
相关产品推荐
相关产品推荐

