从 Angular 中的数组动态创建 formControl
Create formControl dynamically from Arrays in Angular
这是我的第一个问题,所以我希望我准备得足够充分,能够准确地解释问题。 I've also created a stackblitz example for my problem
我从后端收到以下字符串,它应该显示在 table 中。 ('1,2,3@12.5,22.5,27.5@,,'
或 '10,8,5,3,2@17.5,25,32,47,63@2,2,1,0,'
)。长度可以变化。它是 3 个参数(以 @ 分隔)和相应的迭代及其值(以 , 分隔)。
目前我使用 [value]
访问器和 change
方法来拆分字符串并重新组合它。我现在想为各自的值使用一个验证器,它只能与 formControlName 结合使用。 (我知道它也适用于 ngModel,但这只是一个摘录,我们已经在为其他属性使用表单模块)。
我编写了一个验证器,它在我的示例中的第一个输入字段中使用并按预期工作(稍后将出现几个正则表达式,但对于示例我只选择了一个简单的)。
我的问题是:是否可以拆分字符串并将其转换为 FormControls?然后如何访问它并在 HTML?
中显示它
我知道 FormArrays,但不太了解它,因为这是 FormArray 中的一个 FormArray(我猜?-一个用于参数,一个用于迭代值)
我的下一个方法是在我当前的 setBlockValue 方法中包含对输入的验证,该方法在元素上设置一个 .invalid class,然后在输入字段下方显示错误文本。但是那仍然无法帮助我在提交时将表单标记为无效。
我希望这已经够清楚了,希望我的 stackblitz example 能有所帮助。我非常感谢可以解决我的问题的任何资源(如其他问题或文章)。只是还没找到合适的。
我不确定我是否完全理解您想要验证的内容(例如哪些字段),但这里有一个构建动态表单控件的建议:
初始化新表单组:
formGroup = new FormGroup({});
当你有字段(此处为 'yourFields',一个数组)时,你需要添加验证(正如我所说,我不确定那些字段是哪些),你可以遍历所有字段:
this.yourFields.forEach( (field,idx) => {
const CONTROL = formGroup.controls[idx];
this.formGroup.addControl(idx, new FormControl(field));
let controlValidators = []; // if you're going to have more validators per field
// you might also need to check the field (value) and add some custom validator etc.
// so each validator you can push to this 'controlValidators array:
controlValidators.push(Validators.required); // or any other validator you want to push
CONTROL.setValidators(controlValidators);
});
不完全了解你的数据结构,但似乎你需要这样的东西
(我们使用 ReactiveForms)
技术人员:
import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title="Stack Overflow"
form: FormGroup;
blockValue = '10,8,5,3,2@17.5,25,32,47,63@2,2,1,0,';
params = ['param1', 'param2', 'param3'];
constructor(
private _fb: FormBuilder
) {
//can be simplify, depend on aims
this.form = _fb.group({
block: _fb.array([])
});
}
get block(): FormArray {
return this.form.get('block') as FormArray;
}
ngOnInit(): void {
this._buidForm();
this.block.valueChanges
.subscribe(values => {
console.log(values);
})
}
private _buidForm(): void {
const data = this.blockValue.split('@').map(col => col.split(','));
for (let i = 0; i < data[0].length; i++) {
const group = this._fb.group({});
this.params.map((param, idx) => {
const control = this._fb.control(data[idx][i], Validators.required); //or other validators
group.addControl(param, control)
});
this.block.push(group);
}
}
onSubmit(): void {
console.log(this.form.value);
}
}
HTML:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<table formArrayName="block">
<tr>
<td *ngFor="let param of params">{{param}}</td>
</tr>
<tr *ngFor="let group of block.controls; let i = index;" [formGroupName]="i">
<td *ngFor="let col of params">
<input type="text" [formControlName]="col" [style.background]="block.controls[i].get(col)?.invalid ? 'pink':'white'">
</td>
</tr>
</table>
<button type="submit" [disabled]="form.invalid">CHECK</button>
</form>
这是我的第一个问题,所以我希望我准备得足够充分,能够准确地解释问题。 I've also created a stackblitz example for my problem
我从后端收到以下字符串,它应该显示在 table 中。 ('1,2,3@12.5,22.5,27.5@,,'
或 '10,8,5,3,2@17.5,25,32,47,63@2,2,1,0,'
)。长度可以变化。它是 3 个参数(以 @ 分隔)和相应的迭代及其值(以 , 分隔)。
目前我使用 [value]
访问器和 change
方法来拆分字符串并重新组合它。我现在想为各自的值使用一个验证器,它只能与 formControlName 结合使用。 (我知道它也适用于 ngModel,但这只是一个摘录,我们已经在为其他属性使用表单模块)。
我编写了一个验证器,它在我的示例中的第一个输入字段中使用并按预期工作(稍后将出现几个正则表达式,但对于示例我只选择了一个简单的)。
我的问题是:是否可以拆分字符串并将其转换为 FormControls?然后如何访问它并在 HTML?
中显示它我知道 FormArrays,但不太了解它,因为这是 FormArray 中的一个 FormArray(我猜?-一个用于参数,一个用于迭代值)
我的下一个方法是在我当前的 setBlockValue 方法中包含对输入的验证,该方法在元素上设置一个 .invalid class,然后在输入字段下方显示错误文本。但是那仍然无法帮助我在提交时将表单标记为无效。
我希望这已经够清楚了,希望我的 stackblitz example 能有所帮助。我非常感谢可以解决我的问题的任何资源(如其他问题或文章)。只是还没找到合适的。
我不确定我是否完全理解您想要验证的内容(例如哪些字段),但这里有一个构建动态表单控件的建议:
初始化新表单组:
formGroup = new FormGroup({});
当你有字段(此处为 'yourFields',一个数组)时,你需要添加验证(正如我所说,我不确定那些字段是哪些),你可以遍历所有字段:
this.yourFields.forEach( (field,idx) => {
const CONTROL = formGroup.controls[idx];
this.formGroup.addControl(idx, new FormControl(field));
let controlValidators = []; // if you're going to have more validators per field
// you might also need to check the field (value) and add some custom validator etc.
// so each validator you can push to this 'controlValidators array:
controlValidators.push(Validators.required); // or any other validator you want to push
CONTROL.setValidators(controlValidators);
});
不完全了解你的数据结构,但似乎你需要这样的东西 (我们使用 ReactiveForms) 技术人员:
import { Component } from '@angular/core';
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title="Stack Overflow"
form: FormGroup;
blockValue = '10,8,5,3,2@17.5,25,32,47,63@2,2,1,0,';
params = ['param1', 'param2', 'param3'];
constructor(
private _fb: FormBuilder
) {
//can be simplify, depend on aims
this.form = _fb.group({
block: _fb.array([])
});
}
get block(): FormArray {
return this.form.get('block') as FormArray;
}
ngOnInit(): void {
this._buidForm();
this.block.valueChanges
.subscribe(values => {
console.log(values);
})
}
private _buidForm(): void {
const data = this.blockValue.split('@').map(col => col.split(','));
for (let i = 0; i < data[0].length; i++) {
const group = this._fb.group({});
this.params.map((param, idx) => {
const control = this._fb.control(data[idx][i], Validators.required); //or other validators
group.addControl(param, control)
});
this.block.push(group);
}
}
onSubmit(): void {
console.log(this.form.value);
}
}
HTML:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<table formArrayName="block">
<tr>
<td *ngFor="let param of params">{{param}}</td>
</tr>
<tr *ngFor="let group of block.controls; let i = index;" [formGroupName]="i">
<td *ngFor="let col of params">
<input type="text" [formControlName]="col" [style.background]="block.controls[i].get(col)?.invalid ? 'pink':'white'">
</td>
</tr>
</table>
<button type="submit" [disabled]="form.invalid">CHECK</button>
</form>