Angular 响应式表单,传入数据不生成复选框

Angular Reactive Forms, checkboxes are not generated on incoming data

有一个带过滤器的表格。我通过 FormBuilder 创建表单。静态数据没有问题,但我无法处理传入的数据。我需要在航空公司中呈现一组复选框,类似于 transferFilter。在 pathValue 的帮助下,我将字段的值更改为处理后的数据,出现了 10 个元素。在

 {{filtersForm.value | json}} 
中显示和更改数据,嗯,没有出现复选框。我不想将表格拆分成单独的实体,但如果找不到答案,我将不得不重做。

复选框组成方法:

private mapToCheckboxArrayGroup (data: string [], display): FormArray {
    return this.fb.array (
      data.map ((val, i) => {
        return this.fb.group ({
          value: val,
          display: display [i],
          selected: false,
        });
      })
    );
  }

我创建了一个群:

filtersForm: FormGroup = this.fb.group ({
    sort: [this.priceSortItems [0] .attribute],
    transferFilter: this.mapToCheckboxArrayGroup (
      this.availableTransferValue,
      this.availableTransferDisplay
    ),
    minCost: [null],
    maxCost: [null],
    airlines: [null],
  });

我接收数据,处理它并使用以下方法组成一个组:

private refresh $ = new Subject ();

carriers $ = this.refresh $ .pipe (
    startWith (true),
    switchMap (() => this.dataService.getCarriers ()),
    map ((e) => {
      const keys = [... Object.keys (e)];
      const values ​​= [... Object.values ​​(e)];
      const airItems = this.mapToCheckboxArrayGroup (keys, values);
      return airItems;
    }),
    shareReplay (1)
  );

我对表格的变化做出反应:

filterData $ = this.refresh $ .pipe (
    startWith (this.filtersForm.value),
    switchMap (() => this.filtersForm.valueChanges),
    map ((e) => {
      console.log (e);
      console.log (this.filtersForm.controls);
    }),
    shareReplay (1)
  );

我订阅了数据更新,并通过 PathValue 将航空公司组的值从以下方法更改为 formarray:

ngOnInit (): void {

    this.carriers $ .pipe (takeUntil (this.destroy $)). subscribe ((e) => {
      this.filtersForm.patchValue ({
        airlines: e.value,
      });
    });
}

我通过 getter:

将包含数据的数组发送到模板
get carrierFilterArray () {
    const carriers = this.filtersForm.get ('airlines') as FormArray;
    console.log (carriers.value);
    return carriers;
  }

HTML 表格:

<form * ngIf = "filtersForm.value" [formGroup] = "filtersForm" class = "page__menu menu-page">
    <div class = "menu-page__sort" * ngIf = 'priceSortItems'>
      <h3 class = "menu-title"> Sort </h3>
      <div class = "menu-page__sort items" * ngFor = "let elem of priceSortItems; let i = index">
        <input formControlName = "sort" [value] = "elem.attribute" type = "radio" [id] = "elem.value" /> <label
          [for] = "elem.value"> {{elem.display}} </label> <br />
      </div>

      <div class = "menu-page__filter" formArrayName = "transferFilter">
        <h3 class = "menu-title"> Filter </h3>
        <div class = "menu-page__filter items" * ngFor = "let elem of transferFilterArray.controls; let i = index"
          [formGroup] = "elem">
          <input type = "checkbox" [formControl] = "elem.get ('selected')" [value] = "elem.get ('value'). value"
            [id] = "elem.get ('value'). value" />
          <label [for] = "elem.get ('value'). value"> {{elem.get ('display'). value}} </label> <br />
        </div>
      </div>

      <div class = "menu-page__price">
        <h3 class = "menu-title"> Price </h3>
        <p>
          From
          <input formControlName = "minCost" type = "text" />
        </p>
        <p> Before <input formControlName = "maxCost" type = "text" /> </p>
      </div>

      <div class = "menu-page__airlines" formArrayName = "airlines">
        <h3 class = "menu-title"> Airlines </h3>
        <div class = "menu-page__filter items" * ngFor = "let elem of carrierFilterArray.controls; let i = index"
          [formGroup] = "elem">
          <input type = "checkbox" [formControl] = "elem.get ('selected')" [value] = "elem.get ('value'). value"
            [id] = "elem.get ('value'). value" />
          <label [for] = "elem.get ('value'). value"> {{elem.get ('display'). value}} </label> <br />
        </div>
      </div>
      <pre> {{filtersForm.value | json}} </pre>
    </div>
  </form>

结果,我得到了所有正常的过滤器,除了最后一个。下面你可以看到jsonform.value,里面包含了所有的数据

我明白异步需要做什么,但我不明白如何...... 该项目具有教育意义,起初我是用纯 JS 完成的,现在我想在 Angular 中完成它。 如果能给我小费,我将不胜感激。

您需要等到传入数据到达,然后使用所需数据创建表单

并放一个

 <div *ngIf="anyKey">
       **//Here you need to render your form** 
    </div> 

收到您需要生成表格的数据后。

    anyKey = false;
    filtersForm: FormGroup; 

   constructor(){
    this.refresh $ .pipe (
        startWith (true),
        switchMap (() => this.dataService.getCarriers ()),
        map ((e) => {
          const keys = [... Object.keys (e)];
          const values ​​= [... Object.values ​​(e)];
          const airItems = this.mapToCheckboxArrayGroup (keys, values);

          //Create your form here and make the key as true
          this.filtersForm = this.fb.group ({
              sort: [this.priceSortItems [0] .attribute],
              transferFilter: this.mapToCheckboxArrayGroup (
                 this.availableTransferValue,
                 this.availableTransferDisplay
              ),
              minCost: [null],
              maxCost: [null],
              airlines: airItems 
          });
          this.anyKey = true;

        }),
        shareReplay (1)
      );
}

我认为这将有助于您渲染所有控件。