【Angular2】組建通信

組件通信及兩個或者多個組件之間共享信息的方法;

組件之間通信分爲以下幾種情況:

    1、父組件向子組件傳遞數據;

    2、 子組件向父組件傳遞數據;

    3、非嵌套組件之間的通信;

下面將詳細說明如何實現這幾種通信

父組件向子組件傳遞數據:屬性綁定方式([屬性名])

 子組件中通過@Input 裝飾器自定義屬性,父組件綁定這個屬性。

 子組件實現:

import { Component, OnInit,Input } from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() private data: any;//data名字根據引用場景自定義
  constructor() { }
  ngOnInit() {
  }
}


父組件實現:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `<app-child [data]="dataToChild"></app-child>`,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
  private dataToChild: string = ' I am parent';
  constructor() { }
  ngOnInit() {
  }
}


  子組件向父組件傳遞數據:事件綁定 父組件監聽子組件事件

    子組件使用EventEmitter創建自定義事件,並且通過@Output()裝飾器把它作爲屬性暴露出來,父組件通過綁定這個屬性來監聽事件從而獲取子組件數據。

   子組件實現:

import { Component, OnInit} from '@angular/core';
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Output() onCustomEvent: EventEmitter<any> = new EventEmitter();//創建實力
  constructor() { }
  ngOnInit() {
  }
  //
  private emitEvent(){
    this.onCustomEvent.emit('data from child');//通過emit可將需要傳遞的數據發送給父組件
  }
}


  父組件實現:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `<app-child  (onCustomEvent)="onCustom($event)"></app-child>`,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
  constructor() { }
  ngOnInit() {
  }
 onCustom($event){
    console.log($event);//data from child
  }
}


非嵌套組件之間通信:通過服務來通信基於RXJS,該方法也可用於嵌套組件之間的通信

   父組件和子組件通過共享一個服務,利用該服務實現雙向通信。

   服務的定義:

import {Injectable} from "@angular/core";
import {ReplaySubject} from "rxjs/ReplaySubject";
import { Observable } from "rxjs/Observable";
@Injectable()

export class CommunicateService{ 
  private _sendMessage: ReplaySubject<any> = new ReplaySubject<any>(1); 

  /** * 向其他組件發送信息 * @param message 需要發送的信息 * @returns {Observavle<any>} */ 
  public sendMessage(message: any): Observavle<any>{ 
     this._sendMessage.next(message); 
  } 

  /** *訂閱其他組件發送來的消息 * @returns {Observalue<any>} */ 
  public getMessage(): Observable <any>{
     return this._sendMessage.asObservable(); 

  }  
}

 在一個組件中發佈消息,通過服務中定義的sendMessage可廣播一條消息,如果其他組件定於了這條消息,則可接收到

import { Component, OnInit} from '@angular/core';
import {CommunicateService} from "commucate.service"
@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  constructor(private communicateService:CommunicateService) { }
  ngOnInit() {
    this.communicateService.sendMessage('send a message');//發佈一條消息
  }
}

在組件中訂閱消息

import { Component, OnInit } from '@angular/core';
import {CommunicateService} from "commucate.service";

@Component({
  selector: 'app-parent',
  template: `<div>hi</div>`,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {
  constructor(private communicateService:CommunicateService) { }
  ngOnInit() {
    this.communicateService.getMessage().subscribe((message: any)=>{
      console.log(message);//send a message
    });
  }
}


父組件使用子組件的方法: 使用@ViewChild  

父組件調用子組件的方法需要在組件視圖渲染後可能正常運行,否則會報錯;及在生命週期函數AfterViewInit中或者之後調用子組件方法。

子組件實現:在子組件定義公共方法onChildMethod

import { Component, OnInit} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  constructor() { }
  ngOnInit() {
  }

  public onChildMethod(){
    console.log('I am child Method')
  }
}


父組件實現:父組件通過@ViewChild裝飾器可調用子組件中的方法

import { Component, OnInit,ViewChild ,AfterViewInit} from '@angular/core';
import {ChildComponent} from "../child/child.component";

@Component({
  selector: 'app-parent',
  template: `<app-child #child></app-child>`,//定義本地變量child
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit,AfterViewInit {

  @ViewChild('child') //child在模版中定義的變量
  private myChild: ChildComponent;
  //or
  // @Viewchild(ChildComponent)
  // private myChild: ChildComponent;
  constructor() { }
  ngOnInit() {
  }

  ngAfterViewInit(){
    this.myChild.onChildMethond()//I am child Method
  }
}


子組件調用父組件方法;@Inject注入裝飾器實現

子組件實現方式:

import {Component, Inject, OnInit} from '@angular/core';
import {ParentComponent} from "../parent/parent.component";

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {

  constructor(@Inject(ParentComponent) private data: any) {
    data.sayHello();//調用父組件方法
  }

  ngOnInit() {
  }

}


父組件實現方式:在父組件中定義供子組件使用的方法

import {Component, OnInit} from '@angular/core';
@Component({
  selector: 'app-parent',
  template: `<app-child></app-child>`,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit {

  constructor() {}
  ngOnInit() {}
  public sayHello() {
    console.log('hello')
  }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章