在构造函数中使用 FormBuilder 是一种不好的做法吗?

Is using FormBuilder in the constructor a bad practice?

Angular doc here 你可以看到下面那种 implementation.i.e 声明 formBuilderconstructor() 里面的服务。我知道在 constructor() 中使用服务是一种不好的做法。也就是说,我们需要为此使用 ngOnInit()。但我也使用 constructor() 来声明 formBuilder 属性。这种做法太糟糕了吗?我也需要为此使用 ngOnInit() 吗?页面创建会持续到 formBuilder 创建吗?

export class CartComponent {
  items;
  checkoutForm;

  constructor(
    private cartService: CartService,
    private formBuilder: FormBuilder,
  ) {
    this.items = this.cartService.getItems();

    this.checkoutForm = this.formBuilder.group({
      name: '',
      address: ''
    });
  }
}

简短回答,是的,您应该将大部分初始化逻辑留在 ngOnInit 生命周期挂钩中。

根据 OnInit 的 angular 文档,它用于

  • To perform complex initializations shortly after construction.
  • To set up the component after Angular sets the input properties.

因此,在 ngOnInit lifeycle 挂钩上执行诸如获取数据和初始化表单构建器等逻辑会更清晰。

您应该查看 Misko Hevery 的 post,他是 Angular 的团队负责人,他概述了保持构造函数清洁的许多原因。

在构造函数中注入FormBuilder

constructor 中注入 FormBuilder 是推荐的最佳实践,因为 Angular 使用 构造函数注入模式 .

在构造函数中使用 FormBuilder

是否在 constructorngOnInit 生命周期挂钩中初始化响应式表单在很大程度上取决于偏好。但为了保持代码整洁,将初始化逻辑重构为 ngOnInit(或其他方法)是一个好主意。

关于 ngOnInit 的时间,文档状态:

[ngOnInit is a] callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.

因此,ngOnInit 中的表单初始化将在加载页面视图之前进行。


Reactive Forms 的官方 Angular 文档初始化表单如下:

@Component({
  selector: 'app-profile-editor',
  templateUrl: './profile-editor.component.html',
  styleUrls: ['./profile-editor.component.css']
})
export class ProfileEditorComponent {
  profileForm = this.fb.group({
    firstName: ['', Validators.required],
    lastName: [''],
    address: this.fb.group({
      street: [''],
      city: [''],
      state: [''],
      zip: ['']
    }),
    aliases: this.fb.array([
      this.fb.control('')
    ])
  });

  get aliases() {
    return this.profileForm.get('aliases') as FormArray;
  }

  constructor(private fb: FormBuilder) { }
}

Angular Stackblitz Demo