10. Services
Service:
import { Injectable } from '@angular/core';
@Injectable()
export class ArticleService {
private title = 'To give anything less than your best is to sacrifice the gift.';
getTitle() {
return this.title;
}
}
Component:
import { Component } from '@angular/core';
import { ArticleService } from '../article.service';
@Component({
selector: 'app-article',
template: `
<h2>Article Component</h2>
<button class="btn btn-danger" (click)="loadArticle()">Show Article</button>
<h3>{{ title }}</h3>
`
})
export class ArticleComponent {
title = '';
constructor(private articleService: ArticleService) { }
loadArticle() {
this.title = this.articleService.getTitle();
}
}
Article Feature Module:
import { NgModule } from '@angular/core';
import { ArticleComponent } from './article.component';
import { ArticleService } from './article.service';
@NgModule({
declarations: [ ArticleComponent ],
providers: [ ArticleService ],
bootstrap: [ ArticleComponent ],
exports: [ ArticleComponent ]
})
export class ArticleModule { }
AppModule:
import { ArticleModule } from './article/article.module';
imports: [
BrowserModule,
HttpModule,
ReactiveFormsModule,
FormsModule,
RouterModule.forRoot(appRoutes),
ArticleModule
]
Inject Service directly into Component:
import { Component } from '@angular/core';
import { ArticleService } from './article.service';
@Component({
selector: 'app-article',
template: `
<p>Article Component</p>
<button class="btn btn-danger" (click)="loadArticle()">Show Article</button>
<h3>{{ title }}</h3>
`,
providers: [ ArticleService ]
})
export class ArticleComponent {
title = '';
constructor(private articleService: ArticleService) { }
loadArticle() {
this.title = this.articleService.getTitle();
}
}
Polymorphic service utilisation:
export interface IArticleSource {
getArticle(): IArticle;
}
export interface IArticle {
title: string;
body: string;
notes?: string;
}
import { Injectable } from '@angular/core';
@Injectable()
export class ArticleService implements IArticleSource {
private title = 'Angular 4 Love Affair';
private body = 'Dedicated to the smartest and most beautiful woman in the world, Laura.';
getArticle(): IArticle {
return {
title: this.title,
body: this.body
}
}
}
@Injectable()
export class EditorArticleService extends ArticleService implements IArticleSource {
private notes = 'Code with passion.';
constructor() {
super();
}
getArticle(): IArticle {
return Object.assign({}, super.getArticle(), {
notes: this.notes
});
}
}
Components:
import { Component } from '@angular/core';
import { ArticleService, EditorArticleService } from './article.service';
@Component({
selector: 'app-default-view',
template: `
<h3>Default view</h3>
<ng-content></ng-content>
`,
providers: [ ArticleService ]
})
export class DefaultViewComponent { }
@Component({
selector: 'app-editor-view',
template: `
<h3>Editor view</h3>
<ng-content></ng-content>
`,
providers: [ { provide: ArticleService, useClass: EditorArticleService } ]
})
export class EditorViewComponent { }
AppComponent:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="row">
<h1>{{ title }}</h1>
<div class="col-md-6">
<h2>Services</h2>
<app-default-view>
<app-article></app-article>
</app-default-view>
<app-editor-view>
<app-article></app-article>
</app-editor-view>
</div>
<div class="col-md-6">
<app-princess></app-princess>
</div>
</div>
`,
styles: [``]
})
export class AppComponent {
title = 'Angular 4 Love Affair';
}
Directive providers:
import { Directive } from '@angular/core';
import { ArticleService, EditorArticleService } from './article.service';
@Directive({
selector: '[editor-view]',
providers: [{ provide: ArticleService, useExisting: EditorArticleService }]
})
export class EditorViewDirective { }
AppComponent with directive:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<div class="row">
<h1>{{ title }}</h1>
<div class="col-md-6">
<h2>Services</h2>
<app-article editor-view></app-article>
<app-article editor-view></app-article>
</div>
<div class="col-md-6">
<app-princess></app-princess>
</div>
</div>
`,
styles: [``]
})
export class AppComponent {
title = 'Angular 4 Love Affair';
}
Opaque tokens and useValue:
import { OpaqueToken } from '@angular/core';
export const IMAGE_URL = new OpaqueToken('image.url');
ArticleModule:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ArticleComponent } from './article.component';
import { EditorViewDirective } from './editor-view.directive';
import { DefaultViewComponent, EditorViewComponent } from './default-view.component';
import { ArticleService, EditorArticleService } from './article.service';
import { IMAGE_URL } from './image-url.token';
@NgModule({
declarations: [ ArticleComponent, EditorViewDirective, DefaultViewComponent, EditorViewComponent ],
imports: [ CommonModule ],
bootstrap: [ ArticleComponent ],
providers: [ ArticleService, EditorArticleService, { provide: IMAGE_URL, useValue: 'http://vignette2.wikia.nocookie.net/disney/images/1/16/Princess-Ariel-disney-princess-39040276-900-900.jpg'} ],
exports: [ ArticleComponent, EditorViewDirective, DefaultViewComponent, EditorViewComponent ]
})
export class ArticleModule { }
Component:
import { Component, Inject } from '@angular/core';
import { IMAGE_URL } from './image-url.token';
@Component({
selector: 'app-article',
template: `
<img src="{{ imageUrl }}">
<h2>My Polymer Princess</h2>
<p>Author: Nils-Holger Nägele</p>
`
})
export class ArticleComponent {
imageUrl = '';
constructor(@Inject(IMAGE_URL)private _imageUrl) {
this.imageUrl = _imageUrl;
}
}