Angular组件之间的通讯

communication分支,示范组件之间的通讯

// 使用方法
git clone https://git.oschina.net/mumu-osc/learn-component.git
cd learn-component
git pull origin communication
npm install 
ng serve

1.父子组件之间通讯

// parent-and-child.component.ts
import { Component, OnInit, Input, Output, EventEmitter, AfterViewInit, ViewChild } from '@angular/core';
import { ChildComponent } from './child/child.component';

@Component({
  selector: 'parent-and-child',
  templateUrl: './parent-and-child.component.html',
  styleUrls: ['./parent-and-child.component.css']
})
export class ParentAndChildComponent implements OnInit {
  @ViewChild(ChildComponent)
  private childComponent: ChildComponent;

  constructor() { }

  ngOnInit() {
  }
  
  ngAfterViewInit() {
    //this.childComponent.childFn();
  }

  public doSomething():void{
    alert("收到了子组件的自定义事件!");
  }
}
<!-- parent-and-child.component.html  -->
<div class="panel panel-primary">
    <div class="panel-heading">第一种:父子组件之间通讯</div>
    <div class="panel-body">
        <child #child (follow)="doSomething()" panelTitle="设置子组件标题"></child>
        <button (click)="child.childFn()" class="btn btn-success">调用子组件方法</button>
    </div>
</div>
// child.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  private _panelTitle:string="我是子组件";
  
  @Input()
  set panelTitle(panelTitle:string){
    this._panelTitle="【"+panelTitle+"】";
  }

  get panelTitle():string{
    return this._panelTitle;
  }

  @Output()
  public follow=new EventEmitter<string>();

  constructor() { }

  ngOnInit() {
  }

  public emitAnEvent():void{
    this.follow.emit("follow");
  }

  public childFn():void{
    alert("父组件调用子组件方法!");
  }
}
<!-- child.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">{{panelTitle}}</div>
  <div class="panel-body">
    <button (click)="emitAnEvent()" class="btn btn-success">触发一个事件</button>
  </div>
</div>

2.没有父子关系的组件间通讯

<!-- brother.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第二种:没有父子关系的组件间通讯</div>
  <div class="panel-body">
    <child-1></child-1>
    <child-2></child-2>
  </div>
</div>
// event-bus.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';

/**
 * 用来充当事件总线的Service
 */
@Injectable()
export class EventBusService {
  public eventBus:Subject<string> = new Subject<string>();

  constructor() { }

}
// child-1.component.ts
import { Component, OnInit } from '@angular/core';
import { EventBusService } from '../service/event-bus.service';

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

  constructor(public eventBusService:EventBusService) { }

  ngOnInit() {
  }

  public triggerEventBus():void{
    this.eventBusService.eventBus.next("第一个组件触发的事件");
  }
}
<!-- child-1.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第一个组件</div>
  <div class="panel-body">
    <button (click)="triggerEventBus()" class="btn btn-success">触发一个事件</button>
  </div>
</div>
// child-2.component.ts
import { Component, OnInit } from '@angular/core';
import { EventBusService } from '../service/event-bus.service';

@Component({
  selector: 'child-2',
  templateUrl: './child-2.component.html',
  styleUrls: ['./child-2.component.css']
})
export class Child2Component implements OnInit {
  public events:Array<any>=[];

  constructor(public eventBusService:EventBusService) {

  }

  ngOnInit() {
    this.eventBusService.eventBus.subscribe((value)=>{
      this.events.push(value+"-"+new Date());
    });
  }
}
<!-- child-2.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第二个组件</div>
  <div class="panel-body">
      <p *ngFor="let event of events">{{event}}</p>
  </div>
</div>

3.利用localStorge通讯

<!-- local-storage.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第三种方案:利用localStorge通讯</div>
  <div class="panel-body">
    <local-child1></local-child1>
    <local-child2></local-child2>
  </div>
</div>
// local-child1.component.ts
import { Component, OnInit } from '@angular/core';

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

  constructor() { }

  ngOnInit() {
  }

  public writeData():void{
    window.localStorage.setItem("json",JSON.stringify({name:'大漠穷秋',age:18}));
  }
}
<!-- local-child1.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第一个组件</div>
  <div class="panel-body">
      <button (click)="writeData()" class="btn btn-success">写数据</button>
  </div>
</div>
// local-child2.component.ts
import { Component, OnInit } from '@angular/core';

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

  constructor() { }

  ngOnInit() {
  }

  public readData():void{
    var json=window.localStorage.getItem("json");
    var obj=JSON.parse(json);
    console.log(obj.name);
    console.log(obj.age);
  }
}
<!-- local-child2.component.html -->
<div class="panel panel-primary">
  <div class="panel-heading">第二个组件</div>
  <div class="panel-body">
      <button (click)="readData()" class="btn btn-success">读数据</button>        
  </div>
</div>
posted @ 2017-08-23 15:12  郑闯  阅读(1500)  评论(0编辑  收藏  举报