3

Is it possible to render html which is inside app-nav tag already, rather then providing it in templateUrl?

@Component({
  selector: 'app-nav',
  // commented out - templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.scss']
})
export class NavComponent {
  title: string = 'This is my title';
}

Html that is already on the html page.

<app-nav>
  nav works! {{ title }}
</app-nav>

If I uncomment the templateUrl then app-nav will be replaced by nav-component.html page, but I dont want that. I have dynamic html and I want to render that.

2 Answers 2

2

You can use embedded view with ngTemplateOutlet projection. Wrap your content within <app-nav> tags in <template>. Than in your NavComponent find this TemplateRef with ContentChild and insert this templateRef into component's template passing context that contains your title variable to it. Something like this:

@Component({
  selector: 'app-nav',
  templateUrl: './nav.component.html',
  styleUrls: ['./nav.component.scss']
})
export class NavComponent {
  title: string = 'This is my title';

  @ContentChild('defaultTemplate') defaultTemplate = null // get templateRef
}

In nav.component.html create template outlet with relative template context

<template [ngOutletContext]="{ title: title }" [ngTemplateOutlet]="defaultTemplate"></template>

....other component content....

And then in place of component use:

<app-nav>
  <template #defaultTemplate let-title="title">
    nav works! {{ title }}
  </template>
</app-nav>

UPD:

Here is a plunk with example

in app/some.component.ts there is a ngTemplateOutlet projection from app/app.component.ts template

UPD:

Ok, there is a way to get initial content from index.html into the component. You can use APP_INITIALIZER function that will be executed when an application is initialized.

Here is the plunk

  1. See app/root-template.initializer.ts
  2. In app/app.component.ts I just replace relevant property with initial content. This is a bit hacky way and should be done by replacing template in ComponentMetadata which is obtained with Reflect.getMetadata:

    const annotations = Reflect.getMetadata('annotations', NavComponent)
    const meta = annotations.find(annotation => annotation instanceof ComponentMetadata)
    
    meta.template = meta.template.replace(
      '{{ someVarInTemplate }}',
      'initialContentInIndex'
    )
    

This way the component template will have initial index content and it will be parsed by angular. More about Reflect here

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

6 Comments

didn't work, it was replaced by nav.component.html content
Well, it should work. Perhaps there is a mistake somewhere. I've updated my answer with a plunk demoing how that should be implemented
Actually I wanted to put that nav works {{ title }} inside <my-app>Loading...</my-app> my-app tag.. basically that app-nav is root component and not sub component. Is it still possible?
I don't think so. You can find explanation here stackoverflow.com/questions/32568808/…
I came up with a solution. It's not complete but it works. To make it fully right I just need some more investigation but perhaps it's enough for you:)
|
0

@Yaroslav, expanding on your solution:

  1. Looks like a transclusion (in Angular 1 terms), so in Angular 2 you can use ng-content on the inner component.

    <div class="my-component">
      <ng-content></ng-content>
    </div>
    
  2. To get interpolation working on outer transcluded markup, give the element an id and prefix the interpolated content with it.

    <my-component #comp>
      This is my transcluded content! ++{{comp.title}}++
    </my-component>
    
  3. Don't try to transclude from index.html, it's not an angular component, so it doesn't seem to work as the outer component. If you use app.component as the outer and another my.component as inner, it works.

Here's a fork of your plunkr with the changes. plnkr

For reference, I used Todd Motto's excellent article on angular 2 transclusion: ref here.
The angular guide only vaguely refers to ng-content (with a link that 404's), so I wonder if it's disappearing. May be superseded by ngComponentOutlet ref here

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.