What you have here is an interesting combination of content projection and dependency injection.
<ng-template #editTemplate> is being content-projected into Parent component
<Parent>
<ng-template #editTemplate> <--- projected into <Parent>
<button>Edit Me </button>
</ng-template>
</Parent>
so Parent has a direct reference to it via Content Child, if your Parent component looks something like this:
@Component({
selector: 'parent',
template: `
<h2>Parent here!</h2>
<ng-content></ng-content> <--- #editTemplate will get projected here
<child1></child1>
`,
styles: [`h1 { font-family: Lato; }`],
})
export class ParentComponent {
@ContentChild('editTemplate') editTemplate: TemplateRef<any>; // <--- reference to #editTemplate
}
However, child4 is nested several layers deep, so dependency injection is your friend here, otherwise you would need to configure a reference in each layer to complete the chain from Parent down to child4.
Using DI, though, you can inject the Parent component directly into child4, who can then access the editTemplate reference on the Parent component instance and use *ngTemplateOutlet to insert the view from that TemplateRef.
So child4 could look like this:
@Component({
selector: 'child4',
template: `
<h3>Child 4 here!</h3>
<div>And here's the injected template:</div>
<ng-container *ngTemplateOutlet="projectedTemplate"></ng-container> <--- use *ngTemplateOutlet to render editTemplate
`,
styles: [`h1 { font-family: Lato; }`],
})
export class Child4Component {
projectedTemplate: TemplateRef<any>;
constructor(private parentComponent: ParentComponent) {} // <-- inject ParentComponent instance
ngOnInit() {
this.projectedTemplate = this.parentComponent.editTemplate; // <-- set *ngTemplateOutlet to editTemplate
}
}
Here's a StackBlitz showing this approach.