什么是设置此代码的正确方法。我想用户选择复选框,然后将其复选框值推入FormArray
,现在我得到[true,false,false]
输出
data = ['Marka', 'Kilometraza', 'Alu felne'];
addCheckboxes() {
this.data.map((o, i) => {
const control = new FormControl(i === 0);
this.checkboxes.controls.push(control);
});
}
HTML
<div formArrayName="checkboxes" *ngFor="let check of regForm.get('detaljne').get('checkboxes').controls;index as i">
<mat-checkbox [formControlName]="i">{{ data[i] }}</mat-checkbox>
</div>
现在,当第一个复选框选中时,我得到[true,false,false]
输出,但是我想获取所选复选框的值,因此只有所选复选框的值位于该FormArray
中,所以当带有标签'Marka的复选框时比FormArray
的'被检查为['Marka']
答案 0 :(得分:1)
另一种方法是使用自定义表单控件。看看stackblitz
自定义控件接受两种类型的“数据”,像这样的简单数组
data = ['Marka', 'Kilometraza', 'Alu felne'];
或对象数组。您看到的第一个字段是“键”,第二个字段是您的“文本”
dataValue=[{value:1,text:'Marka'},
{value:2,text:'Kilometraza'},
{value:3,text:'Alu felne'}]
代码,我将尝试解释n条注释,例如:
@Component({
selector: 'check-box-list',
template: `
<div [formGroup]="formArray">
<!--see the "special way" we refereed to the elements of formArray
using [fromControl]="variable of loop"
-->
<div *ngFor="let check of formArray.controls;let i=index">
<!--we show or _data[i] or _data[i][text], see below -->
<mat-checkbox [formControl]="check">{{key?_data[i][text]:_data[i]}}</mat-checkbox>
</div>
`,
<!--it's necesary a provider NG_VALUE_ACCESSOR-->
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckBoxListComponent),
multi: true
}
]
})
export class CheckBoxListComponent implements ControlValueAccessor {
formArray: FormArray = new FormArray([])
isValue: boolean = false;
text: string; //I stored in "text" the field that it's showed
key: string; //I stored in "key" the field that has the "value"
_data
@Input() set data(value) {
this._data = value;
//data[0] can be an array or a string/number
//if is an object we get the "keys", e.g.
//data[0]={value:....,text:....}, this.getOrderedKeys return an array ["value","text"]
const keys = typeof (value[0]) == 'object' ? this.getOrderedKeys(value[0]) : null
if (keys) {
this.key = keys[0]
this.text = keys[1]
}
}
onChange;
onTouched;
writeValue(value: any[] | any): void {
//with each value of "data" we create a formControl with value true or false
this.formArray = new FormArray(
this._data.map((x, index) =>
new FormControl(value.indexOf(this.key ? this._data[index][this.key] :
this._data[index]) >= 0)))
//we subscribe to the formArray valueChanges
this.formArray.valueChanges.subscribe((res) => {
this.onTouched() //we mark as touched the custom form control
//we make a filter of data
const response = res.indexOf(true) >= 0 ?
this._data.filter((x, index) => this.formArray.value[index]) :
null
//if has key, return only the array with the keys
this.onChange(response == null ? null : this.key ?
response.map(x => x[this.key]) :
response)
})
}
registerOnChange(fn: any): void {
this.onChange = fn;
}
registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
//if we disabled/enabled the control simply disabled/enabled the controls
this.formArray.controls.forEach(c => {
if (isDisabled)
c.disable();
else
c.enable();
})
}
getOrderedKeys(obj): string[] {
return JSON.stringify(obj)
.replace(/[&\/\\#+()$~%.'"*?<>{}]/g, '')
.split(',')
.map(x => x.split(':')[0]);
}
}
我们可以使用like
<form [formGroup]="form3">
<check-box-list [data]="dataValue" formControlName="checkboxes">
</check-box-list>
</form>
//where
this.form3=new FormGroup(
{
checkboxes:new FormControl([1,3])
}
)
答案 1 :(得分:0)
您可以将从formArray
接收到的值与data
合并:
newCheckboxValue.map((value, index) => value ? data[index] : null).filter(value => value)
将布尔数组转换为标签/空数组,然后删除空