Angular 如何动态更改绑定的formControlName

Angular 如何动态更改绑定的formControlName,angular,angular-reactive-forms,Angular,Angular Reactive Forms,我有一个角度2反应式表单,有四个表单控件,只有一个输入字段。我想让用户一个接一个地填写信息。因此,我将firstControlName分配给Ngonit上的属性调用currentFormControlName,并将其与模板文件中的输入字段绑定。当用户填写其姓名时,该字段将有效,在提交时,我将currentFormControlName属性更改为下一个formControlName。但问题是绑定没有更新。输入字段仍然绑定到名称。当我在输入字段中键入内容时,name的值是更新的,而不是email a

我有一个角度2反应式表单,有四个表单控件,只有一个输入字段。我想让用户一个接一个地填写信息。因此,我将firstControlName分配给Ngonit上的属性调用currentFormControlName,并将其与模板文件中的输入字段绑定。当用户填写其姓名时,该字段将有效,在提交时,我将currentFormControlName属性更改为下一个formControlName。但问题是绑定没有更新。输入字段仍然绑定到名称。当我在输入字段中键入内容时,name的值是更新的,而不是email

app.component.ts

ngOnInit() {
  this.form = this.builder.group({
    'name': ['', Validator.required],
    'email': ['', Validator.email],
    'phone': ['', Validator.required],
    'password': ['', Validator.required],
  });
  this.currentFormControlName = 'name';
}

submit() {
  this.currentFormControlName = 'email'; // Setting it manually just for the demo of this question.
}
app.component.html

<form [formGroup]="form">
  <input type="text" [formControlName]="currentFormControlName">
  <input type="submit" (click)="submit()">
</form>
NGFormName指令 您不能这样做,因为ngFormControlName指令在此处仅使用@Input name一次:

@Directive({selector: '[formControlName]'...})
export class FormControlName extends ... {
  @Input('formControlName') name: string;

  ngOnChanges(changes: SimpleChanges) {
    if (!this._added) this._setUpControl(); <------------ here
    if (isPropertyUpdated(changes, this.viewModel)) {
NGFORM指令 要执行您试图执行的操作,您需要使用ngFormDirective来检查控件是否已更新:

export class FormControlDirective extends NgControl implements OnChanges {
  viewModel: any;

  @Input('formControl') form: FormControl;

  ngOnChanges(changes: SimpleChanges): void {
    if (this._isControlChanged(changes)) {

  private _isControlChanged(changes: {[key: string]: any}): boolean {
    return changes.hasOwnProperty('form');
  }
但是,这是一个独立的指令。

ngFormNameDirective 您不能这样做,因为ngFormControlName指令在此处仅使用@Input name一次:

@Directive({selector: '[formControlName]'...})
export class FormControlName extends ... {
  @Input('formControlName') name: string;

  ngOnChanges(changes: SimpleChanges) {
    if (!this._added) this._setUpControl(); <------------ here
    if (isPropertyUpdated(changes, this.viewModel)) {
NGFORM指令 要执行您试图执行的操作,您需要使用ngFormDirective来检查控件是否已更新:

export class FormControlDirective extends NgControl implements OnChanges {
  viewModel: any;

  @Input('formControl') form: FormControl;

  ngOnChanges(changes: SimpleChanges): void {
    if (this._isControlChanged(changes)) {

  private _isControlChanged(changes: {[key: string]: any}): boolean {
    return changes.hasOwnProperty('form');
  }
但是,这是一个独立的指令。

更新

还可以使用FormControlDirective在控件之间切换

[formControl]="form.get(currentFormControlName)"
旧答案

假设我们有以下几点

template.html

之后,我们的输入元素将管理电子邮件值。因此,如果我们在输入中键入某些内容,它将反映在form.email值中

此解决方案基于

我们只能看到该指令寄存器控件一次。但它也有以下Ngondestry钩子

这给了我一些想法

更新

还可以使用FormControlDirective在控件之间切换

[formControl]="form.get(currentFormControlName)"
旧答案

假设我们有以下几点

template.html

之后,我们的输入元素将管理电子邮件值。因此,如果我们在输入中键入某些内容,它将反映在form.email值中

此解决方案基于

我们只能看到该指令寄存器控件一次。但它也有以下Ngondestry钩子

这给了我一些想法


您是否尝试过使用this.currentFormControlName=this.form.get'name';用同样的方法处理邮件?我认为不可能。。每个输入都需要一个表单控制开关,该开关在表单组的初始化中定义。您可以将ngSwitch与主题结合使用,每次触发提交时,您都会通过显示nexy输入字段来更新表单。您是否尝试使用此选项。currentFormControlName=this.form.get'name';用同样的方法处理邮件?我认为不可能。。每个输入都需要一个表单控制开关,该开关在表单组的初始化中定义。您可以将ngSwitch与主题组合使用,每次触发提交时,您都会通过显示nexy输入字段来更新表单
ngOnChanges(changes: SimpleChanges) {
  if (!this._added) this._setUpControl();
  if (isPropertyUpdated(changes, this.viewModel)) {
    this.viewModel = this.model;
    this.formDirective.updateModel(this, this.model);
  }
}
ngOnDestroy(): void {
  if (this.formDirective) {
    this.formDirective.removeControl(this);
  }
}