I have a custom structural directive on an input element. The input element's onBlur event handler function accepts two template element reference variables - one is a reference its own NgModel, and the other a reference to another NgModel in the template (outside of the element with the attached directive).
After the page loads the 2nd reference variable is undefined on the call to onBlur, but if I click inside the 2nd input element, and go back to the first input element the reference is set to the NgModel, as expected on the Blur event.
I've searched all over, including Stack Overflow, without any luck why this behavior happens. I found that when using *ngIf template reference variables will only work inside of the nested template created by the structural directive, but this behavior is different.
I can switch to using @ViewChild for the template element reference variables, which works, but I'm modifying existing code that needs to stay as close to the original as possible. Everything works as expected without the custom structural directive.
This occurs even with a simple directive as shown below.
Directive snippet
@Directive({ selector: '[appMyDirective]' })
export class MyDirective implements OnInit {
constructor(private templateRef: TemplateRef<any>, private viewContainer: ViewContainerRef) {
ngOnInit() {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
template (HTML) snippet
<mat-form-field>
<input matInput [(ngModel)]="comments" name="comments" #commentsRef="ngModel" (blur)="handleCommentsBlur(commentsRef, titleRef)" *appMyDirective>
</mat-form-field>
<mat-form-field>
<input matInput [(ngModel)]="title" name="title" #titleRef="ngModel">
</mat-form-field>
component TS snippet
handleCommentsBlur(commentsRef: NgModel, titleRef: NgModel) {
// titleRef is undefined after blur event occurs
// However when user clicks in the title element and goes back to the comments then the titleRef holds a reference to the NgModel on the next comments onBlur event
}