首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >分组FormArray

分组FormArray
EN

Stack Overflow用户
提问于 2021-08-26 08:57:26
回答 2查看 445关注 0票数 1

我有一个输入,用户可以输入一个国家和一个城市,用逗号分隔到一个国家和城市的列表。然后,应以将每个城市列在其国家组下的方式显示该列表。

我很难找到正确的方法来构造我的表格。

代码语言:javascript
复制
form = this.fb.group({
    newEntry: [],
    cityToFind: [],
    citiesList: this.fb.array([]),
});

get citiesListForm(): FormArray {
    return this.form.get('citiesList') as FormArray;
}

get searchInput(): FormControl {
    return this.form.get('cityToFind') as FormControl;
}

get newEntryFormControl(): FormControl {
    return this.form.get('newEntry') as FormControl;
}

getCountryFormArray(country: string): FormArray {
    return this.citiesListForm.get(country) as FormArray;
}

addCountrySection(country: string): void {
    this.citiesListForm.push(
      this.fb.group({
        [country]: this.fb.array([]),
      }),
    );
}

addCity(country: string, city: string): void {
    this.getCountryFormArray(prefix).push(
        this.fb.control(nr),
    );
}

ngOnInit(): void {
    this.addCountrySection('USA');
    this.addCountrySection('DE');
    this.addCity('DE', 'Berlin');
    console.log(this.getCountryFormArray('DE')); // This is returning null
}

表格结构正确吗?有人能给我提供一个如何编写模板的例子吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-02 12:31:17

您的方法的主要问题是您正在混合FormArraysFormGroups

考虑一下您想要的结构

代码语言:javascript
复制
{ 
  citiesList: [         // <--------FormArray
    { de: ["Berlin"] },  // <--------FormGroup
    { usa: [] }
  ]
}

因此,如果我想访问"de“元素,我需要执行以下操作

代码语言:javascript
复制
  form[citiesList][0].de

因此,对于反应形式,这将是form.get("citiesList").controls[0].get("de")

我已经在这个stackblitz演示中说明了这一点

这是可行的,但我认为更好的方法是简单地删除外部数组并使其具有以下内容

代码语言:javascript
复制
{ 
  citiesList: { 
    de: ["Berlin"],
    usa: [] 
   }
}

这样,您将添加以国家为属性的控件。

另一种需要考虑的方法可能是使用formArray,如下所示

代码语言:javascript
复制
{ 
  citiesList: [ 
    { country: "DE", cities: ["Berlin"] },
    { country: "USA", cities: [] },
   }
  ]
}
票数 1
EN

Stack Overflow用户

发布于 2021-09-02 13:37:31

FormArrayFormGroup的一个变种,但是区别在于,当使用FormGroup时,数据被序列化为Array而不是object。当您不知道需要多少控件时(当您创建动态表单时),这可能很有用。

这是FormGroupFormArray的角定义

FormGroup将每个子FormControl的值聚合到一个对象中,并以每个控件名称作为键。它通过减少其子级的状态值来计算其状态。例如,如果组中的某个控件无效,则整个组将变得无效。FormArray将每个子FormControl的值聚合到一个数组中。它通过减少其子级的状态值来计算其状态。例如,如果FormArray中的一个控件无效,整个数组就无效。

下面我添加了代码片段和注释,以帮助您了解正在发生的事情。

代码语言:javascript
复制
export class AppComponent {

  form: FormGroup = this.fb.group({
    newEntry: [],
    cityToFind: [],
    citiesList: this.fb.array([])
  });

  constructor(private fb: FormBuilder) {}

  // Get your cityToFind FormArray
  get citiesListForm(): FormArray {
    return this.form.get('citiesList') as FormArray;
  }

  // Get your cityToFind FormControl
  get searchInput(): FormControl {
    return this.form.get('cityToFind') as FormControl;
  }

  // Get your newEntry FormControl
  get newEntryFormControl(): FormControl {
    return this.form.get('newEntry') as FormControl;
  }

  // Get the Country FormArray
  getCountryFormArray(country: string): FormArray {
    const index = this.citiesListForm.controls.findIndex(control => control.get(country));
    return this.citiesListForm.controls[index].get(country) as FormArray;
  }

  // Check if Country Exists
  doesCountryExist(country: string): Boolean {
    return this.citiesListForm.controls.filter(x => x.get(country)).length === 0 ? false : true;
  }

  // Add the Country to citiesList Form
  addCountrySection(country: string): void {
    if (!this.doesCountryExist(country)) {
      this.citiesListForm.push(
        this.fb.group({
          [country]: this.fb.array([])
        })
      );
    }
  }

  // Add either country or country and city
  addCountryAndOrCity(country: string, city: string = null) {
    if (!this.doesCountryExist(country)) {
      this.addCountrySection(country)
    }

    if(city !== null){
      this.getCountryFormArray(country).push(this.fb.control(city))
    }
  }

  ngOnInit(): void {
    // Add just countries
    this.addCountryAndOrCity('USA');
    this.addCountryAndOrCity('DE');

    // Add countries and cities
    this.addCountryAndOrCity('DE', 'Berlin');
    this.addCountryAndOrCity('DE', 'New City 1');
    this.addCountryAndOrCity('USA', 'New City 2');
    this.addCountryAndOrCity('GB', 'leicester');
    this.addCountryAndOrCity('GB', 'london');
    this.addCountryAndOrCity('GB', 'Manchester');

 
    console.log('DE has ' + (this.getCountryFormArray('DE').length) + ' cities');
    // DE has 2 cities

    console.log('GB has ' + (this.getCountryFormArray('GB').length) + ' cities');
    // GB has 3 cities
    
    console.log('USA has ' + (this.getCountryFormArray('USA').length) + ' cities');
    // USA has 1 cities

  }
}

我同意欧文·凯尔文的观点,他说,你把这两者和他提到的结构混合在一起,在我看来更干净,也不那么让人困惑。

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

https://stackoverflow.com/questions/68935531

复制
相关文章

相似问题

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