Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 969f169

Browse files
thelgevoldjuleskremer
authored andcommitted
docs(cb-dynamic-component-loading): add dynamic component loading cookbook (#2896)
s s s s s s s s s s s s s s s
1 parent f0388b5 commit 969f169

File tree

17 files changed

+392
-0
lines changed

17 files changed

+392
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict'; // necessary for es6 output in node
2+
3+
import { browser, element, by } from 'protractor';
4+
5+
/* tslint:disable:quotemark */
6+
describe('Dynamic Component Loader', function () {
7+
8+
beforeEach(function () {
9+
browser.get('');
10+
});
11+
12+
it('should load ad banner', function () {
13+
let headline = element(by.xpath("//h4[text()='Featured Hero Profile']"));
14+
let name = element(by.xpath("//h3[text()='Bombasto']"));
15+
let bio = element(by.xpath("//p[text()='Brave as they come']"));
16+
17+
expect(name).toBeDefined();
18+
expect(headline).toBeDefined();
19+
expect(bio).toBeDefined();
20+
});
21+
});
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// #docregion
2+
import { Component, Input, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
3+
4+
import { AdDirective } from './ad.directive';
5+
import { AdItem } from './ad-item';
6+
import { AdComponent } from './ad.component';
7+
8+
@Component({
9+
selector: 'add-banner',
10+
// #docregion ad-host
11+
template: `
12+
<div class="ad-banner">
13+
<h3>Advertisements</h3>
14+
<template ad-host></template>
15+
</div>
16+
`
17+
// #enddocregion ad-host
18+
})
19+
export class AdBannerComponent implements AfterViewInit, OnDestroy {
20+
@Input() ads: AdItem[];
21+
currentAddIndex: number = -1;
22+
@ViewChild(AdDirective) adHost: AdDirective;
23+
subscription: any;
24+
interval: any;
25+
26+
constructor(private _componentFactoryResolver: ComponentFactoryResolver) { }
27+
28+
ngAfterViewInit() {
29+
this.loadComponent();
30+
this.getAds();
31+
}
32+
33+
ngOnDestroy() {
34+
clearInterval(this.interval);
35+
}
36+
37+
loadComponent() {
38+
this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length;
39+
let adItem = this.ads[this.currentAddIndex];
40+
41+
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(adItem.component);
42+
43+
let viewContainerRef = this.adHost.viewContainerRef;
44+
viewContainerRef.clear();
45+
46+
let componentRef = viewContainerRef.createComponent(componentFactory);
47+
(<AdComponent>componentRef.instance).data = adItem.data;
48+
}
49+
50+
getAds() {
51+
this.interval = setInterval(() => {
52+
this.loadComponent();
53+
}, 3000);
54+
}
55+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// #docregion
2+
import { Type } from '@angular/core';
3+
4+
export class AdItem {
5+
constructor(public component: Type<any>, public data: any) {}
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// #docregion
2+
export interface AdComponent {
3+
data: any;
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// #docregion
2+
import { Directive, ViewContainerRef } from '@angular/core';
3+
4+
@Directive({
5+
selector: '[ad-host]',
6+
})
7+
export class AdDirective {
8+
constructor(public viewContainerRef: ViewContainerRef) { }
9+
}
10+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// #docregion
2+
import { Injectable } from '@angular/core';
3+
4+
import { HeroJobAdComponent } from './hero-job-ad.component';
5+
import { HeroProfileComponent } from './hero-profile.component';
6+
import { AdItem } from './ad-item';
7+
8+
@Injectable()
9+
export class AdService {
10+
getAds() {
11+
return [
12+
new AdItem(HeroProfileComponent, {name: 'Bombasto', bio: 'Brave as they come'}),
13+
14+
new AdItem(HeroProfileComponent, {name: 'Dr IQ', bio: 'Smart as they come'}),
15+
16+
new AdItem(HeroJobAdComponent, {headline: 'Hiring for several positions',
17+
body: 'Submit your resume today!'}),
18+
19+
new AdItem(HeroJobAdComponent, {headline: 'Openings in all departments',
20+
body: 'Apply today'}),
21+
];
22+
}
23+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// #docregion
2+
import { Component, OnInit } from '@angular/core';
3+
4+
import { AdService } from './ad.service';
5+
import { AdItem } from './ad-item';
6+
7+
@Component({
8+
selector: 'my-app',
9+
template: `
10+
<div>
11+
<add-banner [ads]="ads"></add-banner>
12+
</div>
13+
`
14+
})
15+
export class AppComponent implements OnInit {
16+
ads: AdItem[];
17+
18+
constructor(private adService: AdService) {}
19+
20+
ngOnInit() {
21+
this.ads = this.adService.getAds();
22+
}
23+
}
24+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// #docregion
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { NgModule } from '@angular/core';
4+
import { AppComponent } from './app.component';
5+
import { HeroJobAdComponent } from './hero-job-ad.component';
6+
import { AdBannerComponent } from './ad-banner.component';
7+
import { HeroProfileComponent } from './hero-profile.component';
8+
import { AdDirective } from './ad.directive';
9+
import { AdService } from './ad.service';
10+
11+
@NgModule({
12+
imports: [ BrowserModule ],
13+
providers: [AdService],
14+
declarations: [ AppComponent,
15+
AdBannerComponent,
16+
HeroJobAdComponent,
17+
HeroProfileComponent,
18+
AdDirective ],
19+
// #docregion entry-components
20+
entryComponents: [ HeroJobAdComponent, HeroProfileComponent ],
21+
// #enddocregion entry-components
22+
bootstrap: [ AppComponent ]
23+
})
24+
export class AppModule {
25+
constructor() {}
26+
}
27+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// #docregion
2+
import { Component, Input } from '@angular/core';
3+
4+
import { AdComponent } from './ad.component';
5+
6+
@Component({
7+
template: `
8+
<div class="job-ad">
9+
<h4>{{data.headline}}</h4>
10+
11+
{{data.body}}
12+
</div>
13+
`
14+
})
15+
export class HeroJobAdComponent implements AdComponent {
16+
@Input() data: any;
17+
18+
}
19+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// #docregion
2+
import { Component, Input } from '@angular/core';
3+
4+
import { AdComponent } from './ad.component';
5+
6+
@Component({
7+
template: `
8+
<div class="hero-profile">
9+
<h3>Featured Hero Profile</h3>
10+
<h4>{{data.name}}</h4>
11+
12+
<p>{{data.bio}}</p>
13+
14+
<strong>Hire this hero today!</strong>
15+
</div>
16+
`
17+
})
18+
export class HeroProfileComponent implements AdComponent {
19+
@Input() data: any;
20+
}
21+
22+

0 commit comments

Comments
 (0)