Reputation: 17184
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.
Upvotes: 3
Views: 1333
Reputation: 23463
@Yaroslav, expanding on your solution:
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>
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>
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
Upvotes: 0
Reputation: 2137
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
app/root-template.initializer.ts
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
Upvotes: 2