首页 > 解决方案 > 使用 *ngIf 指令后,Angular Reactive Form 输入为空

问题描述

我是 Angular 的新手,我正在尝试实现一种反应形式。我只会放几行代码,这样会更容易理解。我有一个父组件:

page: number;

  ngOnInit() {
    this.addProjectForm = this.formBuilder.group({
         projectId: ['', Validators.required],
         projectName: [''],
         startDate: [''],
         user: [this.user.email],
         country: ['', Validators.required],
         projectType: [this.projectTypeValue, Validators.required],
      });
    this.page = 1;
  }

  clickNext() {
    this.page = this.page + 1;
  }

  clickBack() {
     this.page = this.page - 1;
  }

在父 html 中,我有两个子组件:

<nb-card>
  <nb-card-body id="first-page" *ngIf="page === 1">
    <div class="form-group">
      <label for="projectType" class="label">Bid / Delivery Product</label>
      <nb-select class="select-column" (selectedChange)="saveProjectType();ngOnInit()"
                 id="projectType" formControlName="projectType">
        <nb-option value="bid">Bid</nb-option>
        <nb-option value="deliveryProduct">Delivery Product</nb-option>
      </nb-select>
    </div>
    <delivery-template *ngIf="this.addProjectForm.value.projectType == 'deliveryProduct'"
                       [deliveryProjectForm]="addProjectForm"></delivery-template>
    <bid-template *ngIf="this.addProjectForm.value.projectType == 'bid'"
                             [bidProjectForm]="addProjectForm"></bid-template>
  </nb-card-body>
  <nb-card-body id="second-page" *ngIf="page === 2">
    <!-- some data -->
  </nb-card-body>
  <nb-card-body id="third-page" *ngIf="page === 3">
    <!-- some data -->
  </nb-card-body>
  <nb-card-footer>
    <button nbButton [disabled]="page === 3 || !addProjectForm.valid" class="btn float-left ml-2"
            type="button" (click)="clickNext()">Next
    </button>
    <button nbButton [disabled]="page === 1"
            type="button" (click)="clickBack()">Go Back
    </button>
    <button nbButton [disabled]="page !== 3"
            type="submit" (click)="onSubmit()">Save
    </button>
  </nb-card-footer>
</nb-card>

在子组件(投标模板和交付模板)上,我传递了 addProjectForm:

// Only showing delivery-template because bid-template is almost the same
@Input() deliveryProjectForm: FormGroup;


 ngOnInit() {
   if (this.deliveryProjectForm.contains('projectid')) {
      this.deliveryProjectForm.setControl('projectid', new FormControl('',  Validators.required));
    } else {
      this.deliveryProjectForm.addControl('projectid', new FormControl('',  Validators.required));
    }
    // same for the rest of the properties
 }

 // getters

 get projectId() {
    return this.deliveryProjectForm.get('projectid');
  }
  // same for the rest of the properties

在交付模板 html 上:

<form [formGroup]="deliveryProjectForm">
 <div class="col">
      <div class="form-group">
        <label for="project_id" class="label">Project ID</label>
        <input
          nbInput id="project_id"
          type="text" class="form-control"
          placeholder="Project ID"
          formControlName="projectid">
        <div *ngIf="projectId.invalid && (projectId.dirty || projectId.touched)" class="text-danger">
          <small *ngIf="projectId.errors.required">
            Project ID is required!
          </small>
        </div>
      </div>
    </div>
  <!-- Same for the rest of properties -->
  
</form>

在表单有效并且所有字段都完成的情况下,单击 Next 然后单击 Back() 到输入字段,每个输入字段都是空的,即使在调试器中很难 addProjectForm 具有先前输入的值。但问题是deliveryProjectForm返回后有空值。如果我使用 [hidden] 而不是 *ngIf 值将被恢复。为什么会这样?

谢谢你。

标签: angularformsrxjs

解决方案


当 NgIf 表达式的计算结果为 false 时,它​​所附加的元素(在本例中为组件)将从 DOM 中删除。然后当 NgIf 表达式再次评估为 true 时,会创建全新的组件实例。并为此实例ngOnInit调用。在你里面重置控制值。属性不会从 DOM 中删除元素,这就是为什么使用它时控制值保持不变的原因。ngOnInithidden


推荐阅读