import { Component } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<h3>Selective content projection - using typographer component</h3>
<typographer>
<span sans-serif>This is sans-serif text.</span>
<span serif>This is serif text.</span>
</typographer>
<h3>ngProjectAs - using super-typographer component</h3>
<super-typographer>
<span cursive>This is cursive text.</span>
<span sans-serif>This is sans-serif text.</span>
<span serif>This is serif text.</span>
<span monospace>This is monospace text.</span>
<span fantasy>This is fantasy text.</span>
</super-typographer>
`,
styles: [`
:host >>> .box {
background-color: ivory;
font-size: 1.2em;
margin: 10px;
padding: 5px;
text-align: center;
}
`]
})
export class AppComponent { }
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { TypographerComponent, SerifDirective, SansSerifDirective } from './typographer.component';
import { SuperTypographerComponent, CursiveDirective } from './super-typographer.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [
AppComponent,
TypographerComponent,
SerifDirective,
SansSerifDirective,
SuperTypographerComponent,
CursiveDirective
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
<!DOCTYPE html>
<html>
<head>
<title>Angular QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<!-- 1. Load libraries -->
<!-- Polyfill for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
<script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="https://cdn.rawgit.com/angular/angular.io/74ef87f/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>
import { Component, Directive } from '@angular/core';
@Directive({
selector: '[serif]'
})
export class SerifDirective { }
@Directive({
selector: '[sans-serif]'
})
export class SansSerifDirective { }
@Component({
selector: 'typographer',
template: `
<div>
<div class="box serif">
<ng-content select="[serif]"></ng-content>
</div>
<div class="box sans-serif">
<ng-content select="[sans-serif]"></ng-content>
</div>
</div>
`,
styles: [`
.serif {
font-family: serif;
}
.sans-serif {
font-family: sans-serif;
}
`]
})
export class TypographerComponent { }
import { Component, Directive } from '@angular/core';
@Directive({
selector: '[cursive]'
})
export class CursiveDirective { }
@Directive({
selector: '[monospace]'
})
export class MonospaceDirective { }
@Directive({
selector: '[fantasy]'
})
export class FantasyDirective { }
@Component({
selector: 'super-typographer',
template: `
<div>
<typographer>
<ng-content select="[serif]" ngProjectAs="[serif]"></ng-content>
<ng-content select="[sans-serif]" ngProjectAs="[sans-serif]"></ng-content>
</typographer>
<div class="box cursive">
<ng-content select="[cursive]"></ng-content>
</div>
<div class="box monospace">
<ng-content select="[monospace]"></ng-content>
</div>
<div class="box fantasy">
<ng-content select="[fantasy]"></ng-content>
</div>
</div>
`,
styles: [`
.cursive {
font-family: cursive;
}
.monospace {
font-family: monospace;
}
.fantasy {
font-family: fantasy;
}
`]
})
export class SuperTypographerComponent { }
# Angular2 - Selective content projection and ngProjectAs
## Selective content projection
> Angular 1 developers know this technique as *multi-slot transclusion* (Angular 1.5+).
The content can be selectively projected into multiple locations using `select` attribute of `ng-content` tag.
Refer to the *Typographer* component (*app/typographer.component.ts*) that accepts text elements from the user
and renders them in *serif* and *sans-serif* fonts.
Refer to its usage in *AppComponent* (*app/app.component.ts*). The user can mark *span* elements with *serif* and
*sans-serif* attributes. The *Typographer* component then uses `ng-content` tags with appropriate selector (*[serif]*
and *[sans-serif]*) in its template to cherry-pick elements and place them at desired location.
## ngProjectAs attribute
Let's assume we would like to extend the *Typographer* component with ability to render text in *cursive*, *monospace* and *fantasy* fonts.
We can create a new *SuperTypographer* component (*app/super-typographer.component.ts*) that uses *Typographer* component internally.
Refer to its usage in *AppComponent* (*app/app.component.ts*). The content is first projected into *SuperTypographer* component
template that uses selectors *[cursive]* and *[monospace]* to render text and passes on the elements needed by the embedded *Typographer*
component template. It can be viewed as two level projection and achieved by using `ngProjectAs` attribute in *SuperTypographer*
component template. The value of this attribute should match the `ng-content` selectors in the embedded *Typographer* component template.
Note that this example won't work if `ngProjectAs` attribute is omitted from *SuperTypographer* component template.