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')
  }
}






猜你喜欢

转载自blog.csdn.net/yaomengzhi/article/details/80277702