分類
- 父子組件通信
- 非父子組件通信
實現
-
父子
- 父子組件通信一般使用
@Input和@Output即可實現,參考Angular4學習筆記(六)- Input和Output - 通過Subject
- 父子組件通信一般使用
代碼如下:
message.service.ts
import { Injectable } from '@angular/core';
import {Subject, Observable} from 'rxjs/';
@Injectable()
export class MessageService {
constructor() { }
private subject = new Subject<any>();
sendMessage(something: any) {
this.subject.next(something);
}
clearMessage() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
子組件
home.component.ts
import {Component, EventEmitter, OnInit, Output} from '@angular/core';
import {MessageService} from '../message.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
message: any;
constructor(private messageService: MessageService) {
}
ngOnInit() {
}
sendMessage(): void { // 發送消息
this.message = 'subject';
this.messageService.sendMessage(this.message);
}
clearMessage(): void { // 清除消息
this.messageService.clearMessage();
}
}
home.component.html
<input type="button" value="Subject" (click)="sendMessage()">
<input type="button" value="clear" (click)="clearMessage()">
父組件
app.component.ts
import {Component, OnInit} from '@angular/core';
import {MessageService} from './message.service';
import {Subscription} from 'rxjs/Subscription';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
message: any;
subscription: Subscription;
constructor(private messageService: MessageService) {
}
ngOnInit(): void {
this.subscription = this.messageService.getMessage()
.subscribe(message => { this.message = message; });
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
app.component.html
<app-home></app-home>
<div>{{message | json}}</div>
- 非父子
非父子組件見通信可以通過同一個service來實現。需要注意的是一定要在service中定義一個臨時變量來供傳遞。比如我有兩個組件來傳遞一個Book類型的數據,HomeComponent -> BookComponent,Book和service定義如下:
import {EventEmitter, Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';
export class Book {
name: string;
price: number;
}
@Injectable()
export class BookService {
defaultBook: Book = {name: '《額爾古納河右岸》', price: 20};
bookEventer: EventEmitter<Book> = new EventEmitter();
}
主頁組件HomeComponent,它用來提供數據源,定義如下:
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css'],
encapsulation: ViewEncapsulation.None
})
export class HomeComponent implements OnInit, OnDestroy {
book: Book;
constructor(private bookService: BookService) {
}
ngOnInit() {
this.book = {name: '《萬歷十五年》', price: 10.0};
}
ngOnDestroy() {
this.bookService.bookEventer.emit(this.book);
}
}
書籍組件BookComponent,用來接收數據,定義如下:
import {Component, OnInit, ViewEncapsulation} from '@angular/core';
import {Book, BookService} from './book';
@Component({
selector: 'app-book',
templateUrl: './book.component.html',
styleUrls: ['./book.component.css'],
encapsulation: ViewEncapsulation.None
})
export class BookComponent implements OnInit {
protected subscribeBook: Book;
constructor(private bookService: BookService) {
bookService.bookEventer.subscribe(book => {
bookService.defaultBook = book;
});
}
ngOnInit() {
this.subscribeBook = this.bookService.defaultBook;
}
}
書籍組件模板文件定義如下:
<p>
subscribeBook:{{subscribeBook | json}}
</p>
直接訪問書籍模板對應路由的話,顯示為:

先訪問主頁再訪問書籍模板對應路由的話,顯示為:

參考
RxJS - Subject
Angular 2 組件之間如何通信?
angular2.0+ 模塊之間共享service並訂閱更新
