5

Consider this Angular 6 component

@Component({ template: '<div my-directive>content</div>' }) export class ACustomComponent {} 

What is the simplest way for me to inject the specific instance of the component inside the directive's constructor?

@Directive() export class MyDirective { // how to reference the component whose template hosts this directive? constructor(private hostComponent: Component) {} } 

The simplest way I've thought to do this is to use a service provided in @Component(), store the component instance in a service property, then inject that same service in the directive and retrieve the instance from that property. Wondering if there is a simpler, more generic way (so I don't have to provide that service every time I need to do this) that means the directive doesn't need to know the type of its host component.

PS: My question is different from this one because whereas the other wants the component instance that the directive is directly applied to -- <my-cmp my-directive></my-cmp>, I'm asking for the nearest parent component whether the directive is applied to it directly or to a native HTML element within its template.

Basically, the problem I want to solve is: I need to execute methods within the directive and bind them to the this context of the component that hosts them without the directive knowing the component's type ahead of time.

someMethod.bind(this.hostComponent)(); 
4
  • Have a look at github.com/angular/angular/issues/8277#issuecomment-311032673 if it is helping Commented Aug 7, 2018 at 3:31
  • or may be this github.com/angular/angular/issues/8277#issuecomment-323678013 Commented Aug 7, 2018 at 3:33
  • @ConnorsFan I don't think so. In that posting, the directive is applied specifically to the component, like <my-cmp my-directive></my-cmp>. That isn't the case here. I am looking for the nearest parent component whether the directive is applied directly to it or within its template. I'll edit the question a bit to make that clearer. Commented Aug 7, 2018 at 9:57
  • @Yousefkhan thanks for the suggestion. The first requires me to inject a provider every time (my current solution), and the second allows me only to access the host if the directive is directly applied to it, like <my-cmp my-directive/> Commented Aug 7, 2018 at 10:07

1 Answer 1

3

For a dynamic component type,I do like this, it works on Angular 9.

export class FromItemComponentBase { constructor(private hostElement: ElementRef) { hostElement.nativeElement.__component=this; } } 

@Component({ selector: 'input-error', templateUrl: 'component.html' }) export class FromItemErrorComponent extends FromItemComponentBase { constructor(private hostElement: ElementRef) { super(hostElement); } } @Component({ selector: 'input-password', templateUrl: 'component.html' }) export class FromItemPasswordComponent extends FromItemComponentBase { constructor(private hostElement: ElementRef) { super(hostElement); } } 

@Directive({selector: 'input-error,input-password,input-text'}) export class FormInputDirective { component:FromItemComponentBase; constructor(private hostElement: ElementRef) { this.component=hostElement.nativeElement.__component; } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.