<!DOCTYPE html>
<html>
<head>
<base href="./" />
<title>Angular 2 - Communicating Between Components with Observable & Subject</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- bootstrap css -->
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<!-- polyfill(s) for older browsers -->
<script src="https://unpkg.com/core-js/client/shim.min.js"></script>
<script src="https://unpkg.com/zone.js@0.6.23?main=browser"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3"></script>
<script src="https://unpkg.com/systemjs@0.19.27/dist/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function (err) { console.error(err); });
</script>
</head>
<body>
<app>Loading...</app>
</body>
</html>
/**
* WEB ANGULAR VERSION
* (based on systemjs.config.js in angular.io)
* System configuration for Angular samples
* Adjust as necessary for your application needs.
*/
(function (global) {
System.config({
// DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
transpiler: 'ts',
typescriptOptions: {
// Complete copy of compiler options in standard tsconfig.json
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"typeRoots": [
"../../node_modules/@types/"
]
},
meta: {
'typescript': {
"exports": "ts"
}
},
paths: {
// paths serve as alias
'npm:': 'https://unpkg.com/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/common': 'npm:@angular/common@2.2.1/bundles/common.umd.js',
'@angular/compiler': 'npm:@angular/compiler@2.2.1/bundles/compiler.umd.js',
'@angular/core': 'npm:@angular/core@2.2.1/bundles/core.umd.js',
'@angular/forms': 'npm:@angular/forms@2.2.1/bundles/forms.umd.js',
'@angular/http': 'npm:@angular/http@2.2.1/bundles/http.umd.js',
'@angular/http/testing': 'npm:@angular/http@2.2.1/bundles/http-testing.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser@2.2.1/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic@2.2.1/bundles/platform-browser-dynamic.umd.js',
'@angular/router': 'npm:@angular/router@3.2.1/bundles/router.umd.js',
// other libraries
'rxjs': 'npm:rxjs@5.0.0-rc.3',
'ts': 'npm:plugin-typescript@4.0.10/lib/plugin.js',
'typescript': 'npm:typescript@2.0.3/lib/typescript.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.ts',
defaultExtension: 'ts'
},
rxjs: {
defaultExtension: 'js'
}
}
});
if (!global.noBootstrap) { bootstrap(); }
// Bootstrap the `AppModule`(skip the `app/main.ts` that normally does this)
function bootstrap() {
// Stub out `app/main.ts` so System.import('app') doesn't fail if called in the index.html
System.set(System.normalizeSync('app/main.ts'), System.newModule({ }));
// bootstrap and launch the app (equivalent to standard main.ts)
Promise.all([
System.import('@angular/platform-browser-dynamic'),
System.import('app/app.module')
])
.then(function (imports) {
var platform = imports[0];
var app = imports[1];
platform.platformBrowserDynamic().bootstrapModule(app.AppModule);
})
.catch(function(err){ console.error(err); });
}
})(this);
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/index';
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const routing = RouterModule.forRoot(appRoutes);
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { MessageService } from './_services/index';
@Component({
moduleId: module.id,
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnDestroy {
message: any;
subscription: Subscription;
constructor(private messageService: MessageService) {
// subscribe to home component messages
this.subscription = this.messageService.getMessage().subscribe(message => { this.message = message; });
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
}
<!-- main app container -->
<div class="jumbotron">
<div class="container">
<div class="col-sm-8 col-sm-offset-2">
<div *ngIf="message" class="alert alert-success">{{message.text}}</div>
<router-outlet></router-outlet>
</div>
</div>
</div>
<!-- credits -->
<div class="text-center">
<p>
<a href="http://jasonwatmore.com/post/2016/12/01/angular-2-communicating-between-components-with-observable-subject" target="_top">Angular 2 - Communicating Between Components with Observable & Subject</a>
</p>
<p>
<a href="http://jasonwatmore.com" target="_top">JasonWatmore.com</a>
</p>
</div>
export * from './message.service';
import { Component } from '@angular/core';
import { MessageService } from '../_services/index';
@Component({
moduleId: module.id,
templateUrl: 'home.component.html'
})
export class HomeComponent {
constructor(private messageService: MessageService) {}
sendMessage(): void {
// send message to subscribers via observable subject
this.messageService.sendMessage('Message from Home Component to App Component!');
}
clearMessage(): void {
// clear message
this.messageService.clearMessage();
}
}
<div class="col-md-6 col-md-offset-3">
<h1>Home</h1>
<button (click)="sendMessage()">Send Message</button>
<button (click)="clearMessage()">Clear Message</button>
</div>
export * from './home.component';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
import { MessageService } from './_services/index';
import { HomeComponent } from './home/index';
@NgModule({
imports: [
BrowserModule,
routing
],
declarations: [
AppComponent,
HomeComponent
],
providers: [
MessageService
],
bootstrap: [AppComponent]
})
export class AppModule { }
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}