Reputation: 963
I have seen many Angular 2 pages that loop through a hierarchy of nativeElements. They don't work in Angular 4, 5, ... I need to add a directive to a "workspace" DIV. There will be other Divs that are parent of workspace and others are child DIVs nested to any level. This directive must detect a mouse click for the "workspace" div OR any of the nested divs and I must determine that it is in fact a nest child or the workspace -- and NOT some other div above workspace or outside workspace.
This is derived from one of the many examples on the web:
import {Directive, ElementRef, HostListener} from '@angular/core';
@Directive({
selector: '[shMonitorInfoClicks]'
})
export class MonitorInfoClicksDirective {
public elementRef;
constructor(private myElement: ElementRef) {
this.elementRef = myElement;
}
@HostListener('document:click', ['$event'])
public onClick(event: Event): void {
let clickedComponent = event.target;
let inside = false;
do {
if (clickedComponent === this.elementRef.nativeElement) {
inside = true;
break;
} else {
clickedComponent = clickedComponent.parentNode; <<<<====== see below
}
} while (clickedComponent);
if(inside) {
console.log('inside');
} else {
console.log('outside');
}
}
}
The test HTML:
<div>
This is outside the workspace
</div>
<div shMonitorInfoClicks [ngStyle]="{'height': '200px', 'width': '300px', 'border': '1px solid red'}">
This is the workspace
<div [ngStyle]="{'height': '100px', 'width': '100px', 'border': '1px solid green'}">
A workspace child
</div>
</div>
When I pause in the Chrome debugger, I am able to use the console to make parentNode or parentElement work. However, I can't get past Typescript/Angular CLI. I made sure I'm running the @latest Angular. (It's 5).
Any help will be appreciated. Thanks in advance.
Upvotes: 1
Views: 3438
Reputation: 8306
The event.target.parentNode
reference doesn't get past the compiler because the compiler is viewing event.target
as an EventTarget
, which doesn't have a parentNode
property. In order to inform the compiler what your event.target
really is, you need to use a type assertion to cast the event.target
it's real type, which in your case is an HTMLElement
:
const target = event.target as HTMLElement;
Now you will have access to target.parentNode
.
The reason you are able to see it in the console is because that is printing out the event.target
at runtime (types not included), but Angular's event object's target
property returns something else. You can see a little more information here: https://angular.io/guide/user-input#type-the-event, but it's hard to find more information on it.
Anyways, you can always use the console to figure out what the type of your event.target
really is and then cast your event.target
to that type in the code. Then you can access all those properties you see in the console without the compiler throwing a fit :)
Upvotes: 1