以 master-detail reactive angular 2 形式添加动态行

Add dynamic row in a master-detail reactive angular 2 form

我需要创建一个能够动态添加详细信息行的主从表单。当我必须加载数据时,问题出现在编辑模式下。实际上,当我通过 formbuilder 添加 formgroups 时,我仍然不知道有多少详细信息("Recapiti")会从 Web 返回给我 API ...有没有解决方案?

.....
@Component({
  selector: 'formutenti',
  templateUrl: './formutenti.component.html',
  //styleUrls: ['./formutenti.component.css']
})
export class FormUtentiComponent implements OnInit, AfterViewInit {
  complexForm: FormGroup;
  submitted: boolean;
  recapiti: Recapito[];
  myGroupName = ['Recapiti'];
 
  ngOnInit() {
    this.complexForm = this.fb.group({
      nome: ['', Validators.compose([Validators.required, Validators.maxLength(20)])],
      cognome: ['', Validators.compose([Validators.required, Validators.maxLength(20)])],
      myArray: this.fb.array([this.createItems(this.recapiti) //<==this.recapiti is undefined
      ])
    });

    if (this.data) {
      this.utentiService.getUtente(this.data)
        .subscribe(data => {
          (<FormControl>this.complexForm.controls['nome']).setValue(data['Nome'], { onlySelf: true });
          (<FormControl>this.complexForm.controls['cognome']).setValue(data['Cognome'], { onlySelf: true });
          this.recapiti = data['Recapiti'];
        });
    }
  }

  constructor(private fb: FormBuilder, private utentiService: UtentiService, private sharedService: SharedService, private notificationService: NotificationsService) {
  }

  createItems(recapiti: Recapito[]): FormGroup[] {
    let formGroups: FormGroup[];
    if (this.complexForm) {
      const control = <FormArray>this.complexForm.controls['myArray'];
      for (var _i = 0; _i < recapiti.length; _i++) {
        formGroups.push(this.fb.group({
          [recapiti[_i].IDrecapito]: this.fb.group({
            name: [recapiti[_i].IDrecapito],
            indirizzo: [''],
            telefono: [''],
            email: [''],
          })
        }))
      }
    }
    return formGroups;
  }
 
  initArray(nameObj: any) {
    return this.fb.group({
      [nameObj]: this.fb.group({
        name: [nameObj],
        indirizzo: [''],
        telefono: [''],
        email: [''],
      })
    })
  }
 
  addArray(newName: string) {
    const control = <FormArray>this.complexForm.controls['myArray'];
    this.myGroupName.push(newName);
    control.push(this.initArray(newName));
    (<HTMLInputElement>document.getElementById('newName')).value = '';
  }
 
  removeDataKey(i: number) {
    const control = <FormArray>this.complexForm.controls['myArray'];
    control.removeAt(i);
    this.myGroupName.splice(i, 1);
  }
}

使用 FormArray 是正确的解决方案。您只是对应用程序中的执行顺序有疑问。

如果按照您的代码进行操作,您会发现在获取数据之前使用数据初始化了 FormGroup。

在我的应用程序中,代码如下所示:

ngOnInit(): void {
    this.productForm = this.fb.group({
        productName: ['', [Validators.required,
                           Validators.minLength(3),
                           Validators.maxLength(50)]],
        productCode: ['', Validators.required],
        starRating: ['', NumberValidators.range(1, 5)],
        tags: this.fb.array([]),
        description: ''
    });

    this.productService.getProduct(id)
        .subscribe(
            (product: IProduct) => this.onProductRetrieved(product),
            (error: any) => this.errorMessage = <any>error
        );
}

onProductRetrieved(product: IProduct): void {
    this.product = product;

    // Update the data on the form
    this.productForm.patchValue({
        productName: this.product.productName,
        productCode: this.product.productCode,
        starRating: this.product.starRating,
        description: this.product.description
    });
    this.productForm.setControl('tags', this.fb.array(this.product.tags || []));
}

请注意,它在 onProductRetrieved 方法中,在检索到数据后填充 FormArray。

希望对您有所帮助。