10

I believe the answer to this is "no", but is there a method/service in Angular where I can pass in a component's root DOM node (e.g. <foo-component>) and receive the component instance (e.g. FooComponent)?

I couldn't find an associated SO post on this.

Example:

<foo-component id="foo"></foo-component>

const fooElement: HTMLElement = document.getElementById('foo');
const fooInstance: FooComponent = getInstanceFromElement(fooElement);

Is there a method in Angular like getInstanceFromElement?

Edit:

I can't use ViewChild... I'm looking for a global service I can use. Suppose I am not invoking this method from the component class. I'm well acquainted with ViewChild/ContentChild and they are not what I'm looking for. Suppose I am in a globally injected service and am trying to do something like the following:

class MyService {
  constructor() {}

  getInstanceFromElement(element: HTMLElement): Component<T> {
    // Is there some special helper service I can use here?
  }
}
5
  • 2
    How do you get the component DOM node? Why can't you get the component instance directly (e.g. with a template reference variable)? Commented Oct 15, 2019 at 0:18
  • Suppose it's just not feasible to add template references, and that I just have access to a DOM node. Commented Oct 15, 2019 at 0:26
  • Aren't you just looking for ViewChild? Commented Oct 31, 2019 at 14:50
  • stackoverflow.com/questions/51640307/… Commented Oct 31, 2019 at 18:19
  • 1
    What is that you are trying to achieve? Commented Nov 3, 2019 at 19:28

4 Answers 4

2

Yes, there is. @ViewChild() was the right hint here. Let me give you an example:

@ViewChild('editorStepsDomElements', { static: false, read: ElementRef }) fooComponentDomElement: ElementRef;
@ViewChild('fooComponent', { static: false, read: FooComponent }) fooComponent: FooComponent;

So basically you can define in the ViewChild() what you want to get. Just set the read parameter to either ElementRef (for getting the DOM element), or to the respective component you want to get.

Sign up to request clarification or add additional context in comments.

1 Comment

OP says he can't use ViewChild
1
+25

Try like this:

Working Demo

Template:

<foo-component #foo></foo-component>

TS:

  @ViewChild('foo', { static: false }) fooComponent: FooComponent;

  ngAfterViewInit() {
    console.log(this.fooComponent)
  }

3 Comments

OP says he can't use ViewChild
@devpato He said it 3 hours back and i answered this 5 days back
I know. I'm letting you know for you to update the answer and people to stop up voting an answer that is not correct based on the OP requirements.
-1

Yes, You can do with Dynamic Component Loader to attach a component dynamically to the DOM. Follow this link

1 Comment

This isn't what I'm trying to do. I added a code snippet to hopefully make it clearer.
-1

This is simple in Angular. @ViewChild/@ViewChildren and @ContentChild/@ContentChildren return the component reference/QueryList<Component> by default during the ngAfterViewInit and ngAfterContentInit lifecycles.

For Example:

@Component({
  template:`<foo-component></foo-component>`
})
export TestComponent implements AfterViewInit {
  @ViewChild(FooComponent, { static: false }) fooComponent: FooComponent;

  ngAfterViewInit() {
    console.log(this.fooComponent)
  }

For directives, you can use a template variable if the directive specifies an exportAs. See https://netbasal.com/angular-2-take-advantage-of-the-exportas-property-81374ce24d26 for a good write up.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.