Reputation: 684
When using <ng-content></ng-content>
for content projection, it is usually possible to access the parent component via dependency injection:
@Component({
selector: 'app-parent',
template: 'Parent / <ng-content></ng-content>'
})
export class ParentComponent {}
@Component({
selector: 'app-child',
template: 'Child / Has parent: {{parentComponent != null}}'
})
export class ChildComponent {
constructor(@Optional() public parentComponent: ParentComponent) {}
}
<app-parent>
<app-child></app-child>
</app-parent>
<!-- this will output Parent / Child / Has parent: true -->
However when adding another layer, this does not seem to work although app-parent
is still the direct parent of app-child
in the DOM:
@Component({
selector: 'app-host',
template: `Host / <app-parent><ng-content></ng-content></app-parent>`
})
<app-host>
<app-child></app-child>
</app-host>
<!-- this will output: Host / Parent / Child / Has parent: false -->
See also this stackblitz for an example: https://stackblitz.com/edit/angular-ivy-e7c6i8?file=src/app/app.component.html
Is there some way to access ParentComponent
from ChildComponent
even in a nested scenario?
Upvotes: 1
Views: 1189
Reputation: 4790
This will not work, because ChildComponent
is being projected as content of the HostComponent
. So in the eyes of the HierarchicalInjector ChildComponent
and ParentComponent
are siblings, since they are both children of the HostComponent
.
You might be able to get around it by making your HostComponent
a provider of the ParentComponent
by using forwardRef
and assigning the value in proper lifecycle hook, but if that works it still would be sketchy to say the least, since the actual value of the reference would be null during injection in dependent components.
Basically, trying to access parent component directly is a bad practice and you should try to avoid that. Instead use @Input / @Output for communication between Child - Parent. If there's a lots of logic going on, you can instead create a separate service (which could be either singleton, i.e. provided on the application level, or be provided by other component, e.g. ParentComponent
, and hence be scoped to one Parent-Child pair.).
Upvotes: 2