首页 > 解决方案 > Angular 2+ - 无法交换 FormArray 的 2 个元素

问题描述

我正在使用 FormControls 的 FormArray。我有一组显示在表格中的对象。每个对象都有一个显示在文本区域中的可编辑属性。这些文本区域被添加到 FormArray。

用户应该能够向上或向下移动每一行。为此,我交换了数组的 2 个元素。

交换对象后,我很好地交换了 FormArray 元素,但是之后 FormArray 元素在页面上出现错误(交换了其他对象属性,但未交换 TextAreas)。当我调试时,在交换对象后,相应的 FormArray 元素中的值与交换前保持相同,因此看起来也需要交换 FormArray 值。

当我尝试只交换对象而不交换 FormArray 元素时,页面上的一切看起来都很好。但是,当我尝试更新交换行的 textarea、保存并刷新时,textarea 中的文本显示不正确。此外,当我尝试将 textarea 更新为无效值时,会显示不正确的错误消息(指的是错误的行)。显然 FormArray 元素实际上并没有被交换,尽管它们在页面上看起来是交换的。

从这两种情况来看,当对象被交换时,textarea 控件似乎没有刷新。

我正在使用的 html 模板的片段是:

<form [formGroup]="standardForm" novalidate>
<table>
    <thead>
      <tr>
        <th></th>
      </tr>
     </thead>
    <tbody>
      <ng-container formArrayName="standardArray">
        <ng-template ngFor let-question [ngForOf]="standardQuestions" let-i="index">
          <tr>
            <td>
              <textarea formControlName="{{i}}" id="Question_{{question.Id}}" name="Question_{{question.Id}}" [maxlength]="maxQuestionTextLength"
                        class="form-control" appElasticText (blur)="saveStandardQuestion(i)"
                        [class.is-invalid]="checkForStandardError(i) "></textarea>
              <span class="invalid-feedback" *ngIf="checkForStandardError(i)?.required">Question is required.</span>
            </td>
          </tr>
        </ng-template>
      </ng-container>
    </tbody>
  </table>
</form>

组件中的代码:

    this.standardForm =
        this.formBuilder.group({
          standardArray: this.formBuilder.array([])
        });
      this.standardArray = this.standardForm.get('standardArray') as FormArray;
   _.each(this.standardQuestions, q => {
     this.createStandardFormArrayItem(q);
   });


createStandardFormArrayItem(question: InterviewQuestionModel) {
    const ctrl = new FormControl('', [Validators.required, Validators.maxLength(this.maxQuestionTextLength)]);
    this.standardArray.push(ctrl);
    ctrl.patchValue(question.Question);
  }

在这里,我尝试交换 2 个元素:

private swapStandard(i: number, j: number) {
    const question = this.standardQuestions[i];
    const swapQuestion = this.standardQuestions[j];
    // Here is call to the server to swap the elements

       const temp = this.standardQuestions[j];
        this.standardQuestions[j] = this.standardQuestions[i];
        this.standardQuestions[i] = temp;

// Here is the logic to swap elements of the standardArray that resulted in incorrect display on the page. 

// const c1 = this.standardArray.at(i) as FormControl;
// const c2 = this.standardArray.at(j) as FormControl;
// c1.setValue(this.standardQuestions[i].Question);
// c2.setValue(this.standardQuestions[j].Question);

      }

我试图添加超时,但它也不起作用:

setTimeout(() =>{
       const c1 = this.standardArray.at(i) as FormControl;
        const c2 = this.standardArray.at(j) as FormControl;
        c1.setValue(this.standardQuestions[i].Question);
        c2.setValue(this.standardQuestions[j].Question);
}, 500);

我试图从 FormArray 中删除这两个项目并再次插入它们,从交换的对象中设置它们的值,但它仍然不起作用。

请建议在交换 FormArray 控件的值后如何刷新 UI。

标签: angularangular-reactive-formsformarray

解决方案


推荐阅读