分组 FormArray
Grouping a FormArray
我有一个输入法,用户可以在其中输入以逗号分隔的国家和城市到国家和城市列表。
然后,该列表应以每个城市都列在其国家/地区组下的方式显示。
我正在努力寻找构建表单的正确方法。
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
}
表单结构是否正确?谁能给我提供一个如何编写模板的例子。
您的方法的主要问题是您混合了 FormArrays
和 FormGroups
。
考虑您想要的结构
{
citiesList: [ // <--------FormArray
{ de: ["Berlin"] }, // <--------FormGroup
{ usa: [] }
]
}
所以如果我想访问“de”元素,我需要做一些类似
的事情
form[citiesList][0].de
因此对于反应形式,这将是 form.get("citiesList").controls[0].get("de")
中对此进行了说明
这可行,但我认为更好的方法是简单地删除外部数组并在下面设置
{
citiesList: {
de: ["Berlin"],
usa: []
}
}
有了这个,您将添加国家/地区为 属性 的控件。
可以考虑的另一种方法是使用如下所示的 formArray
{
citiesList: [
{ country: "DE", cities: ["Berlin"] },
{ country: "USA", cities: [] },
}
]
}
FormArray
是 FormGroup
的变体,但不同之处在于使用 [=12= 时数据被序列化为 Array
而不是 object
].当您不知道需要多少控件时(创建动态表单时)这可能很有用
这里是Angular对FormGroup and FormArray
的定义
A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children. For example, if one of the controls in a group is invalid, the entire group becomes invalid.
A FormArray aggregates the values of each child FormControl into an array. It calculates its status by reducing the status values of its children. For example, if one of the controls in a FormArray is invalid, the entire array becomes invalid.
下面我添加了一段带有注释的代码,以帮助您了解正在发生的事情。
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
}
}
我同意 Owen Kelvin,他说你将两者混合在一起,而且他提到的结构在我看来更清晰,更少混淆。
我有一个输入法,用户可以在其中输入以逗号分隔的国家和城市到国家和城市列表。 然后,该列表应以每个城市都列在其国家/地区组下的方式显示。
我正在努力寻找构建表单的正确方法。
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
}
表单结构是否正确?谁能给我提供一个如何编写模板的例子。
您的方法的主要问题是您混合了 FormArrays
和 FormGroups
。
考虑您想要的结构
{
citiesList: [ // <--------FormArray
{ de: ["Berlin"] }, // <--------FormGroup
{ usa: [] }
]
}
所以如果我想访问“de”元素,我需要做一些类似
的事情 form[citiesList][0].de
因此对于反应形式,这将是 form.get("citiesList").controls[0].get("de")
这可行,但我认为更好的方法是简单地删除外部数组并在下面设置
{
citiesList: {
de: ["Berlin"],
usa: []
}
}
有了这个,您将添加国家/地区为 属性 的控件。
可以考虑的另一种方法是使用如下所示的 formArray
{
citiesList: [
{ country: "DE", cities: ["Berlin"] },
{ country: "USA", cities: [] },
}
]
}
FormArray
是 FormGroup
的变体,但不同之处在于使用 [=12= 时数据被序列化为 Array
而不是 object
].当您不知道需要多少控件时(创建动态表单时)这可能很有用
这里是Angular对FormGroup and FormArray
的定义A FormGroup aggregates the values of each child FormControl into one object, with each control name as the key. It calculates its status by reducing the status values of its children. For example, if one of the controls in a group is invalid, the entire group becomes invalid.
A FormArray aggregates the values of each child FormControl into an array. It calculates its status by reducing the status values of its children. For example, if one of the controls in a FormArray is invalid, the entire array becomes invalid.
下面我添加了一段带有注释的代码,以帮助您了解正在发生的事情。
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
}
}
我同意 Owen Kelvin,他说你将两者混合在一起,而且他提到的结构在我看来更清晰,更少混淆。