If I have a component with a form input and I want to detect the two statements in the OnInit block as events inside my directive, what is the correct way to do this? I have had luck with 'input' and 'ngModelChange', but none of the events I try to listen to catch the patchValue() method for model driven forms or the straight assignment for template driven forms (even though it reflects in the DOM).
Here is my Component:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms'
@Component({
selector: 'my-app',
template:
`
<h5>Model form input</h5>
<form [formGroup]="inputForm">
<input patchable-input formControlName="input" />
</form>
<h5>Template form input</h5>
<input patchable-input [(ngModel)]="input" />
`
})
export class AppComponent implements OnInit {
inputForm = new FormGroup({
input: new FormControl('')
})
input = '';
ngOnInit() {
this.inputForm.patchValue({
input: 'testing patch'
})
this.input = 'testing override'
}
}
Here is my Directive:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[patchable-input]'
})
export class PatchableInputDirective {
@HostListener('ngModelChange', ['$event']) ngOnChanges($event) {
console.log($event);
}
}
and a minimal reproduction in StackBlitz (watch the console)
You have to implement AfterViewInit
instead of OnInit
. The reason for that is at this point in the life cycle your directive has been initialized and has subscribed to the ngModelChange
event via the @HostListener
decorator.
See also the Angular Life Cycle Hooks documentation.
import { Component, AfterViewInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms'
@Component({
selector: 'my-app',
template:
`
<h5>Model form input</h5>
<form [formGroup]="inputForm">
<input patchable-input formControlName="input" />
</form>
<h5>Template form input</h5>
<input patchable-input [(ngModel)]="input" />
`
})
export class AppComponent implements AfterViewInit {
inputForm = new FormGroup({
input: new FormControl('')
})
input = '';
ngAfterViewInit() {
this.inputForm.patchValue({
input: 'testing patch'
})
}
}