Angular4學習筆記(十)- 組件間通訊

分類

  • 父子組件通訊
  • 非父子組件通訊

實現

代碼以下:html

message.service.tsjson

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();
  }
}

子組件segmentfault

home.component.tsangular2

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.htmlapp

<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.htmlthis

<app-home></app-home>
<div>{{message | json}}</div>
  • 非父子

非父子組件見通訊能夠經過同一個service來實現。須要注意的是必定要在service中定義一個臨時變量來供傳遞。好比我有兩個組件來傳遞一個Book類型的數據,HomeComponent -> BookComponentBook和service定義以下:.net

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,它用來提供數據源,定義以下:code

@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並訂閱更新

相關文章
相關標籤/搜索