购物车
登陆 / 注册
微信扫码登陆

推荐手册

组件通信

本文介绍的内容是组件通信的常用方式:@Input、@Output、@ViewChild、模板变量、MessageService、Broadcaster (Angular 1.x $rootScope 中 $on、$broadcast ) 和 Pub - Sub 模式、RxJS Subject 存在的问题。

输入属性 (父组件 -> 子组件)

counter.component.ts

import { Component, Input } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>当前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    increment() {
        this.count++;
    }
    decrement() {
        this.count--;
    }
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <exe-counter [count]="initialCount"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
}

输出属性 (子组件 -> 父组件)

counter.component.ts

import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
    selector: 'exe-counter',
    template: `
      <p>当前值: {{ count }}</p>
      <button (click)="increment()"> + </button>
      <button (click)="decrement()"> - </button>
    `
})
export class CounterComponent {
    @Input() count: number = 0;
    @Output() change: EventEmitter<number> = new EventEmitter<number>();
    increment() {
        this.count++;
        this.change.emit(this.count);
    }
    decrement() {
        this.count--;
        this.change.emit(this.count);
    }
}

app.component.ts

import { Component } from '@angular/core';
@Component({
  selector: 'exe-app',
  template: `
   <p>{{changeMsg}}</p> 
   <exe-counter [count]="initialCount" 
    (change)="countChange($event)"></exe-counter>
  `
})
export class AppComponent {
  initialCount: number = 5;
  changeMsg: string;
  countChange(event: number) {
    this.changeMsg = `子组件change事件已触发,当前值是: ${event}`;
  }
}

模板变量

child.component.ts

import {Component} from '@angular/core';
@Component({
  selector: 'child-component',
  template: `I'm {{ name }}`
})
export class ChildComponent {
  public name: string;
}

parent.component.ts

import {Component, OnInit} from '@angular/core';
import {ChildComponent} from './child-component.ts';
@Component({
  selector: 'parent-component',
  template: `
    <child-component #child></child-component>
    <button (click)="child.name = childName">设置子组件名称</button>
  `
})
export class ParentComponent implements OnInit {
  private childName: string;
  constructor() { }
  ngOnInit() { 
    this.childName = 'child-component';
  }
}

@ViewChild 装饰器

child.component.ts

import { Component, OnInit } from '@angular/core';
@Component({
    selector: 'exe-child',
    template: `
      <p>Child Component</p>  
    `
})
export class ChildComponent {
    name: string = '';
}

app.component.ts

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from './child.component';
@Component({
  selector: 'my-app',
  template: `
    <h4>Welcome to Angular World</h4>
    <exe-child></exe-child>
  `,
})
export class AppComponent {
  @ViewChild(ChildComponent)
  childCmp: ChildComponent;
  ngAfterViewInit() {
    this.childCmp.name = 'child-component';
  }
}

使用 MessageService - 基于 RxJS Subject

message.service.ts

import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class MessageService {
    private subject = new Subject<any>();
    sendMessage(message: string) {
        this.subject.next({ text: message });
    }
    clearMessage() {
        this.subject.next();
    }
    getMessage(): Observable<any> {
        return this.subject.asObservable();
    }
}

home.component.ts

import { Component } from '@angular/core';
import { MessageService } from './message.service';
@Component({
    selector: 'exe-home',
    template: `
    <div>
        <h1>Home</h1>
        <button (click)="sendMessage()">Send Message</button>
        <button (click)="clearMessage()">Clear Message</button>
    </div>`
})
export class HomeComponent {
    constructor(private messageService: MessageService) {}
    sendMessage(): void {
        this.messageService.sendMessage('Message from Home Component to App Component!');
    }
    clearMessage(): void {
        this.messageService.clearMessage();
    }
}

app.component.ts

import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { MessageService } from './message.service';
@Component({
    selector: 'my-app',
    template: `
    <div>
       <div *ngIf="message">{{message.text}}</div>
       <exe-home></exe-home>
    </div>
    `
})
export class AppComponent implements OnDestroy {
    message: any;
    subscription: Subscription;
    constructor(private messageService: MessageService) {
        this.subscription = this.messageService
                                .getMessage().subscribe( message => { 
                                    this.message = message; 
                                 });
    }
    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

使用 Broadcaster - 基于 RxJS Subject

实现 Angular 1.x 中的 $rootScope 对象中 $on 和 $broadcast 的功能。

broadcaster.ts

import { Injectable } from '@angular/core';
import {Subject} from 'rxjs/Subject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/filter';
import 'rxjs/add/operator/map';
interface BroadcastEvent {
  key: any;
  data?: any;
}
@Injectable()
export class Broadcaster {
  private _eventBus: Subject<BroadcastEvent>;
  constructor() {
    this._eventBus = new Subject<BroadcastEvent>();
  }
  broadcast(key: any, data?: any) {
    this._eventBus.next({key, data});
  }
  on<T>(key: any): Observable<T> {
    return this._eventBus.asObservable()
      .filter(event => event.key === key)
      .map(event => <T>event.data);
  }
}

child.component.ts

import { Component } from '@angular/core';
@Component({
    selector: 'child'
})
export class ChildComponent {
  constructor(private broadcaster: Broadcaster) {}
  registerStringBroadcast() {
    this.broadcaster.on<string>('MyEvent')
      .subscribe(message => {
        ...
      });
  }
  emitStringBroadcast() {
    this.broadcaster.broadcast('MyEvent', 'some message');
  }
}
网站导航
标签地图
学习路径
视频教程
开发软件
旗下子站
php中文网
phpstudy
技术文章
文档工具
关于我们
企业合作
人才招聘
联系我们
讲师招募
QQ交流群
QQ官方交流群
微信公众号
微信公众号