Thomas Sablik
Thomas Sablik

Reputation: 16454

Angular2: How to get a reference to a ViewChild in a child component

I have a component (App) that contains another component (Comp). App gets string content from a database and forwards it by @Input() to Comp. This string content can contain html tags like

Some text before <a>Click</a> Some Text after

In Comp this content is supposed to be rendered and some event listeners are supposed to be added. Therefor this content is added using [innerHtml]. Because (click) is removed in [innerHtml] a reference to the a tag is needed and a event listener is supposed to be added with addEventListener. But I can't find a way to reference the a tag since an ElementRef to a component doesn't contain nativeElement.

What is the best way to get this plunker running? https://plnkr.co/edit/xVUu0LJ02YVnBO25Zr4j?p=preview

Upvotes: 5

Views: 3263

Answers (2)

eko
eko

Reputation: 40647

Direct DOM access is discouraged in Angular2

Here's a hacky way to do it with direct dom access.

Define an event listener in the child comp and filter the event:

document.querySelector('body').addEventListener('click', function(event) {
      if (event.target.tagName.toLowerCase() === 'a') {
         that.updateCounter.next(true);
      }
    });

then use an EventEmitter to update the counter.

Plunker: https://plnkr.co/edit/vm44niH781j4mEQHDpLU?p=preview

Upvotes: 1

Pac0
Pac0

Reputation: 23129

In Angular2, you want to make your nested components to communicate only to their direct parent / children.

you can create a click handler for your "a" tag in your component "Comp".

In your component Comp, you can create a @Output() variable (basically an EventEmitter), that you will fire in your click handler

In the main app component, you can listen to your new EventEmitter and handle the event.

For example :

in Comp :

@Output myClickEventEmitter: EventEmitter

aTagClickHandler (e) {
    myClickEventEmitter.emit(e)
}

in App template

in App Component :

myCompClickHandler(e) {
    console.log(e);
}

I hope my syntax is correct here, and that it helped .

EDIT :

You should also be able to reference an inner component using the #variableName attribute in your a tag like that :

in template :

<a #variableName > </a> 

in component :

@ViewChild('variableName') myATag;

Upvotes: 0

Related Questions