首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用formGroup将对象数组绑定到angular8和bind数组

如何使用formGroup将对象数组绑定到angular8和bind数组
EN

Stack Overflow用户
提问于 2020-02-23 08:50:01
回答 1查看 12.7K关注 0票数 5

嗨,我使用了反应性表单将对象数组绑定到formArray,但是在这里,如果我选择一个节中的任何一个项,然后单击“向右移动/向左移动”,那么整个对象已经从一个部分移动到另一个部分。但是该功能运行良好,但我无法检测form.valuechanges()中从一个部分到另一个部分生成的chnage。有人能帮我检测一下变化吗?因为已从一个部分移到另一个部分,这里我想要更改检测,但功能必须正常工作,我指的是要从一个部分移动到另一个部分的整个对象。

提前谢谢。

我已经在这里使用demo2了,我希望我以前发布的demo1能够像这样使用work数组工作。演示2

演示:演示1

TS:

代码语言:javascript
复制
 private settingsGroupInfoForm() {
    if (!this.agentDetailsList) {
      // Add
     this.agentGroupViewInfoForm = this.FB.group({
          agentGroupView: this.FB.array(
            this.agentInView.map(x=>(x))
          ),
        })
    } else {
      // Edit
      if (this.agentDetailsList) {

       this.agentGroupViewInfoForm = this.FB.group({
          agentGroupView: this.FB.array(this.agentInView.map(x=>(x))),

      })
      }
      this.agentGroupViewInfoForm.valueChanges.subscribe(data => {
          this.formEdit = true;
          console.log('agentGroupViewInfoForm', this.formEdit)
        })
      }
    }

HTML:

代码语言:javascript
复制
 <div class="card-body overflow-auto py-0" *ngIf="agentGroupViewInfoForm"
            [formGroup]="agentGroupViewInfoForm">
                <ul class="list-group list-group-flush" *ngFor="let child of agentInView"   name="agentInGroup" formArrayName="agentGroupView">
                  <li class="list-group-item {{isInActiveItems(child) ? 'active' : ''}}" (click)="toggleActiveItem(child)">
                    {{child.value}}
                  </li>
                </ul>
              </div>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-27 08:15:45

你的问题

  • 您有两个相同类型的项数组。
  • 您希望为每个数组呈现一个表单数组。
  • 您希望能够在数组之间移动项。
  • 您希望能够将表单值绑定回提交时的项。

设计

对于角度上几乎所有基于组件的问题,您应该首先考虑模型。你的模型是国王,其他一切都是围绕着它建立的。

在演示中,您要在列表之间移动项目。您正在更新模型并将HTML绑定到该模型。没有什么不对的-这是正确的方法和工作。

这里的另一个挑战是,您也希望移动表单组。我们仍然需要考虑模型--首先,同时考虑移动相关状态,同时在列表之间移动项目。

抽象地说,您目前

代码语言:javascript
复制
list1: [];
selected1: [];

list2: [];
selected2: [];

如果要将项目从1 -> 2中移除,则移动方法将将所选项从items1移到items2。很简单。

一旦添加了表单,就会有如下结构:

代码语言:javascript
复制
list1: [];
selected1: [];
form1: FormGroup;
formArray1: FormArray;

list2: [];
selected2: [];
form2: FormGroup;
formArray2: FormArray;

当您将项目从1 -> 2中移动时,您将继续将项目从list1移动到list2,但现在还需要从formArray1中删除相关项并将其添加到formArray2

我正在存储对表单数组的引用,以便以后更容易地使用它们。

构建表单

使用表单数组可以说是这个答案中最复杂的部分。表单数组的关键是HTML结构模仿您构建的FormGroup对象的结构。

我们可以使用FormBuilder从数组构建表单,并按如下方式绑定到它:

component.ts

代码语言:javascript
复制
buildForm() {
  this.model = [ 
    { value: 'a' }, { value: 'b' }, { value: 'c' }
  ];

  // create a form group for each item in the model
  const formGroups = this.model.map(x => this.formBuilder.group({
    value: this.formBuilder.control(x.value)
  }));

  // create a form array for the groups
  const formArray = this.formBuilder.array(formGroups);

  // create the top-level form
  this.form = this.formBuilder.group({
    array: formArray
  });
}

并绑定到HTML中,如下所示:

代码语言:javascript
复制
<form [formGroup]="form1" (submit)="onSubmit()">
  <div formArrayName="array">
    <div *ngFor="let item of list1; let i = index" [formGroupName]="i">
      <input formControlName="value" />
    </div>
  </div>
  <button>Submit</button>
</form>

这将为数组中的每个项生成一个输入,分别包含值"a“、"b”和"c“。

移动物品

在数组之间移动项是一个简单的javascript问题。我们需要splice源数组和push到目标数组。

若要将项目从列表1移动到列表2:

代码语言:javascript
复制
// move selected items from model 1
this.selected1.forEach(item => {
  const index = this.list1.indexOf(item);
  this.list1.splice(index, 1);
  this.list2.push(item);
});

this.selected1.length = 0;

这将循环遍历列表1中的每个选定项目,将其从列表中剪接,然后将其推入列表2,然后清除所选的项目;

移动形群

您将在移动项目的同时移动表单组。它在概念上是相似的-你从一个移除,然后添加到另一个。您从您的模型构建了表单数组,因此您知道您的索引匹配。

代码语言:javascript
复制
// move selected items from model 1
this.selected1.forEach(item => {
  const index = this.list1.indexOf(item);
  const formGroup: FormGroup = this.formArray1.controls[index] as FormGroup;

  this.list1.splice(index, 1);

  // move between form arrays
  this.formArray1.removeAt(index);
  this.formArray2.push(formGroup);

  this.list2.push(item);
});

请注意,在表单数组之间有2行可以移动,它们看起来类似于用于在常规数组之间移动的2行。

formArray.removeAt(index)formArray.push(formGroup)正在搬家。表单数组的不同之处在于,我们需要首先使用this.formArray1.controls[index] as FormGroup;获得对它的引用。

演示:https://stackblitz.com/edit/angular-3cwnsv

警诫

在此设计中,从数组和窗体中移除和添加的顺序非常重要。您正在将HTML绑定到数组和表单。您正在创建输入数组,方法是遍历数组,并将每个项绑定到表单数组中的ith组。如果首先从表单中删除,则现在在数组中有n项,在窗体数组中有n - 1项。当试图绑定到未定义的nth form组时,将出现错误。

您现在正在使用多个操作执行事务。

除了确保删除并按正确的顺序添加之外,还有一种方法是使用OnPush更改检测。阅读这一点,因为这是一个很好的策略,除了最简单的应用程序。

下一步

为了回答的目的,我保持了我的演示的简单性。就目前情况而言,它并不是特别可伸缩或可重用的。有很多重复的代码和错误的命名,试图避免被与应用程序相关的嵌套组件和属性名称分散注意力。

实际上,您可能希望创建一个子组件,负责我复制的大量代码。这个设计绝对超出了这个问题的范围。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60360555

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档