I have the following template
<template #myTemplate >
<input type="text" class="input-sm" required />
</template>
I refer this template to formGroup, like this
<div [formGroup]="testForm">
<div [ngTemplateOutlet]="myTemplate" [ngOutletContext]="{item: item}">
</div>
This template #myTemplate
is provided by the end user of the component.
The problem here is, it is not getting recognised by the formGroup and hence not able to validate. On googling I found we need to register this control with NG_VALUE_ACCESSOR. So added a attribute directive to the input element.
@Directive({
selector: '[control]',
providers: [
{
provide: NG_VALUE_ACCESSOR, multi: true,
useExisting: forwardRef(() => TempControl),
}],
host: {'(change)': 'onChange($event.target.value)', '(blur)':
'onTouched()'},
})
export class TempControl implements ControlValueAccessor{
onChange = (_) => {};
onTouched = () => {}
constructor(private renderer: Renderer2, private elem: ElementRef) {
}
writeValue(value) : void {
this.renderer.setProperty(this.elem.nativeElement, 'value', value);
}
registerOnChange(fn: (_: any) => void): void {
this.onChange = fn;
}
registerOnTouched(fn){ this.onTouched = fn; }
}
And I have added this directive to the input element, like below
<template #myTemplate >
<input type="text" class="input-sm" control required />
</template>
But the element is not recognised by the form group even after registering it with NG_VALUE_ACCESSOR
and implementing ControlValueAccessor
.
I understand templateref is not moved inside the formGroup, only a reference is made available there and hence the formGroup is not able to detect the input. What is the right solution in this case?
I referred this SO answer, Does just implementing the ControlValueAccessor
makes the enclosing formGroup aware of this new input? After doing this I checked FormGroup.controls
which doesn't have this new input.
I have reproduced the problem in this stackblitz