Angular4学习笔记(十)- 组件间通信

时间:2023-12-18 16:07:02

分类

  • 父子组件通信
  • 非父子组件通信

实现

代码如下:

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 -> BookComponentBook和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>

直接访问书籍模板对应路由的话,显示为:

Angular4学习笔记(十)- 组件间通信

先访问主页再访问书籍模板对应路由的话,显示为:

Angular4学习笔记(十)- 组件间通信

参考

RxJS - Subject

Angular 2 组件之间如何通信?

angular2.0+ 模块之间共享service并订阅更新