Angular, ControlValueAccessor. Как по клику на кнопку отчекнуть соответствующий кастомный чекбокс в форме?
Не могу понять, как в Parent компоненте можно повлиять на состояние чекбокса в кастомном компоненте, т.е. отчекнуть кастомный чекбокс:
https://stackblitz.com/edit/uncheck-checkboxes-in-form-by-click-on-button
Ответы (1 шт):
Автор решения: Татьяна Компаниец
→ Ссылка
Проблема решилась добавлением свойства checked: true/false https://stackblitz.com/edit/uncheck-checkboxes-in-form-by-click-on-button
app.component.ts:
data = [
{id: 1, name: 'apple', checked: false},
{id: 2, name: 'orange', checked: true},
{id: 3, name: 'banana', checked: true},
{id: 4, name: 'cherry', checked: false}
]
form = new FormGroup({
food: new FormControl()
})
selectedItems = [];
constructor() {
this.form.controls.food.valueChanges
.subscribe((res: number[]) => {
console.log('res', res);
this.data.forEach(el => {
el.checked = res.indexOf(el.id) >= 0;
});
this.selectedItems = this.data.filter(d => d.checked);
})
}
ngOnInit(): void {
this.selectedItems = this.data.filter(d => d.checked);
}
remove(id) {
this.data.find(x => x.id == id).checked = false; // change checkbox state
console.log(this.customCheckbox);
this.customCheckbox.removeControl(id); // remove apropriate form control
}
app.component.html:
<form [formGroup]="form">
<app-custom-checkbox formControlName="food" [data]="data"></app-custom-checkbox>
</form>
<br>
<div *ngFor="let item of selectedItems">
id: <strong>{{ item.id }}</strong>, name: <strong>{{ item.name }}</strong>, checked: <strong>{{ item.checked }}</strong>
<span (click)="remove(item.id)"> remove</span>
</div>
custom-checkbox.component.ts
@Component({
...
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CustomCheckboxComponent),
multi: true
}]
})
export class CustomCheckboxComponent implements ControlValueAccessor {
@Input() data: any;
constructor() {}
form = new FormGroup({
array: new FormArray([])
})
writeValue(obj: any): void {}
registerOnChange(fn: any): void {
this.form.controls.array.valueChanges.subscribe(fn)
}
registerOnTouched(fn: any): void {}
setDisabledState ? (isDisabled: boolean) : void {}
ngOnInit(): void {
this.data.forEach(d => { // if there is already checked checboxes in data (by default)
if (d.checked) this.addControl(d.id)
});
}
onSelect(e, id) {
e.target.checked ?
this.addControl(id) :
this.removeControl(id)
}
addControl(id) {
(this.form.controls.array as FormArray).push(new FormControl(id))
this.data.find(x => x.id == id).checked = true;
}
public removeControl(id) {
var index = (this.form.controls.array as FormArray).value.indexOf(id); // find index of control for the removing
(this.form.controls.array as FormArray).removeAt(index);
this.data.find(x => x.id == id).checked = false; // change checked state of checkbox in data
}
}
custom-checkbox.component.html
<div [formGroup]="form">
<div formArrayName="array" *ngFor="let item of data; index as i">
<input type="checkbox" (change)="onSelect($event, item.id)" [checked]="item.checked">
<label>{{item.id}} {{ item.name }}</label> / {{item.checked}}
</div>
</div>