0

If I have a component BaseComponent that looks like

<ng-container *ngTemplateOutlet="tpl"></ng-container>

And another component OtherComponent that passes a template into it

<base-component [tpl]="tpl">Some content for ng-content</base-component>

<ng-template #tpl>
  <ng-content></ng-content>
  <!-- How do I get access to ng-content passed to the base component instead of other component? --> 
</ng-template>

Is it possible for me to get the ng-content that is passed into the component exposed to the template?

What I am trying to achieve is to define a template elsewhere in the application that has the ability to define where a component should project content into the template.

More on what I am trying to achieve can be seen in this question Use configurable templates in Angular and where I have gotten to in trying to solve that problem in this StackBlitz https://stackblitz.com/edit/angular-lj3x1f.

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
  • 1
    What do you mean by, "to get access to ng-content?" Access in what, the base component controller or base component template? – Rafael Jan 24 '19 at 03:42
  • I would like the content rendered in the template to be "Some content for ng-content" – Adrian Brand Jan 24 '19 at 03:49
  • Yeah, you want content projected at that point, and? What's the issue, I'm not understanding? – Rafael Jan 24 '19 at 03:50
  • Are you trying to say that you want the base component to have a handle to the template's projected content so it can project it elsewhere inside of itself?? – Rafael Jan 24 '19 at 03:52
  • If I pass a template into a component, how do I get that template to project the content that was passed into the component that is using it. ng-content in the template get the content from the component that created the template, not the content using the template. – Adrian Brand Jan 24 '19 at 03:53
  • "If I pass a template into a component" ...okay... "how do I get that template to project the content that was passed into the component..." That makes zero sense. The content that is passed into the component IS the template. – Rafael Jan 24 '19 at 03:57
  • If you read this question https://stackoverflow.com/questions/54319504/use-configurable-templates-in-angular and look at this stack blitz https://stackblitz.com/edit/angular-lj3x1f you might see what I am trying to do. – Adrian Brand Jan 24 '19 at 03:59
  • Have you found a solution to your problem? – jo_va Jan 26 '19 at 09:25
  • Not yet, it is Australia Day long weekend so haven't put in any computer time in the last few days. My thinking is that I am going to have to override each component rather than at a base component level. So if you want to use a text question you will need to supply the template for your own text question component and wont be able to do it for all components at once on the base components. A little extra boilerplate but only once per question type so should still work. – Adrian Brand Jan 28 '19 at 04:29

2 Answers2

1

I had all but forgotten about trying to get this to work but the answer came to me in a dream the other night out of nowhere.

In the base component we can put ng-content in a template and then pass that template to the user defined template's context.

<ng-container *ngTemplateOutlet="tpl;context:{ $implicit: contentTemplate }">
</ng-container>

<ng-template #contentTemplate>
  <ng-content></ng-content>
</ng-template>

Then when we define the the template that we are going to pass into the base component we can use that template in the context to display the ng-content.

<base-component [tpl]="tpl">Some content for ng-content</base-component>

<ng-template #tpl let-contentTemplate>
  <ng-template *ngTemplateOutlet="contentTemplate"></ng-template>
</ng-template>

Here is a StackBlitz

https://stackblitz.com/edit/angular-tvqjgv

Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
0

What you are doing is quite interesting but I think the content projection can't work since <ng-content> works at the component level and not at the template level.

It does not "produce" content but simply projects or moves existing content into a component.

Because of this the lifecycle of the projected content is bound to where it is declared, not where it is displayed, and thus cannot work with templates, which can be instantiated at runtime multiple times.

See this other question and this article.

However I didn't find any official documentation from angular.

jo_va
  • 13,504
  • 3
  • 23
  • 47