分类
- 父子组件通信
- 非父子组件通信
实现
-
父子
- 父子组件通信一般使用
@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并订阅更新