angular2 组件通讯

五种方式

1. @input

把父组件中的值传递到子组件中,子组件声明变量时,前面用@input装饰器。
例子1:
子组件中

import { Component, Input } from '@angular/core';
import { Hero } from './hero';
@Component({
    selector: 'hero-child',
    template: `
      <h3>{{hero.name}} says:</h3>
      <p>I, {{hero.name}}, am at your service, {{masterName}}.</p>
  `
})
export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}

父组件中

import { Component } from '@angular/core';
import { HEROES } from './hero';
@Component({
  selector: 'hero-parent',
  template: `
    <h2>{{master}} controls {{heroes.length}} heroes</h2>
    <hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </hero-child>  `
})
export class HeroParentComponent {
  heroes = HEROES;
  master: string = 'Master';
}

2. setter

结合@input可以实现对数据的get,set
例子2:
子组件中

  import { Component, Input } from '@angular/core';
@Component({
  selector: 'name-child',
  template: '{{name}}' 
})
export class NameChildComponent {
  private _name = '';
  @Input()
  set name(name: string) {
    this._name = (name && name.trim()) || '<no name set>';
  }
  get name(): string { return this._name; }
}

父组件中

import { Component } from '@angular/core';
@Component({
  selector: 'name-parent',
  template: `
  <h2>Master controls {{names.length}} names</h2>
  <name-child *ngFor="let name of names" [name]="name"></name-child>
  `
})
export class NameParentComponent {
  // Displays 'Mr. IQ', '<no name set>', 'Bombasto'
  names = ['Mr. IQ', '   ', '  Bombasto  '];
}

这个例子中,子组件中定义了一个私有变量_name,接受父组件的name,且定义了name的get和set方法。通过set设置默认值,通过get返回定义的_name

3.声明周期钩子 ngOnChanges

监听属性的变化
例子3:

import { Component, Input, OnChanges, SimpleChange } from '@angular/core';
@Component({
  selector: 'version-child',
  template: `
    <h3>Version {{major}}.{{minor}}</h3>
    <h4>Change log:</h4>
    <ul>
      <li *ngFor="let change of changeLog">{{change}}</li>
    </ul>
  `
})
export class VersionChildComponent implements OnChanges {
  @Input() major: number;
  @Input() minor: number;
  changeLog: string[] = [];
  ngOnChanges(changes: {[propKey: string]: SimpleChange}) {
    let log: string[] = [];
    for (let propName in changes) {
      let changedProp = changes[propName];
      let to = JSON.stringify(changedProp.currentValue);
      if (changedProp.isFirstChange()) {
        log.push(`Initial value of ${propName} set to ${to}`);
      } else {
        let from = JSON.stringify(changedProp.previousValue);
        log.push(`${propName} changed from ${from} to ${to}`);
      }
    }
    this.changeLog.push(log.join(', '));
  }
}
import { Component } from '@angular/core';
@Component({
  selector: 'version-parent',
  template: `
    <h2>Source code version</h2>
    <button (click)="newMinor()">New minor version</button>
    <button (click)="newMajor()">New major version</button>
    <version-child [major]="major" [minor]="minor"></version-child>
  `
})
export class VersionParentComponent {
  major: number = 1;
  minor: number = 23;
  newMinor() {
    this.minor++;
  }
  newMajor() {
    this.major++;
    this.minor = 0;
  }
}

在这个例子中,通过ngOnChanges监测了两个数据的变化,并在数据变化时,将数据打印到日志上.
一旦数据有变化,那么ngOnChanges就会执行,且变化的数据会进入到changes对象中.

4.EventEmitter

它是一个输出属性,所以通常带@Output装饰器
例子4
子组件

import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
  selector: 'my-voter',
  template: `
    <h4>{{name}}</h4>
    <button (click)="vote(true)"  [disabled]="voted">Agree</button>
    <button (click)="vote(false)" [disabled]="voted">Disagree</button>
  `
})
export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;
  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}

父组件

import { Component }      from '@angular/core';
@Component({
  selector: 'vote-taker',
  template: `
    <h2>Should mankind colonize the Universe?</h2>
    <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
    <my-voter *ngFor="let voter of voters"
      [name]="voter"
      (onVoted)="onVoted($event)">
    </my-voter>
  `
})
export class VoteTakerComponent {
  agreed = 0;
  disagreed = 0;
  voters = ['Mr. IQ', 'Ms. Universe', 'Bombasto'];
  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}

(onvoted)='onvoted($event)'中的(onvoted)对应子组件中的@Output() onVoted = new EventEmitter<boolean>();通过this.onVoted.emit(agreed);触发, onvoted($event)对应父组件的onvoted方法.$event为传递参数的一个媒介

5.本地变量

用该方法可以在父组件中读取子组件中的属性以及方法
例子:5
父组件中

...
template:`
<child #ch></child> 
<button (click)='ch.test'>test<button>
 `
...

子组件中

import { Component }    from '@angular/core';
@Component({
selector:'child'
...
})
export class  childComponent{
test(){
  console.log(' this is a test')
}
}

通过这个方法,可以在父组件中,读取子组件内的方法

6.@viewchild()

例子6

import { AfterViewInit, ViewChild } from '@angular/core';
import { Component }                from '@angular/core';
import { A }  from './A';

@Component({
...
})
export class B implements AfterViewInit{
 @ViewChild(A)
  private aa: A;

start(){
  this.aa.start()
 }
}

将子组件作为viewchild 注入到父组件中,就可以通过该对象读取A组件里的方法以及属性

7.通过服务

import { Injectable } from '@angular/core';

通过此编写服务,在两个组件内都引入,那么就可以同时使用这个实例,个人理解为一个仓库,组件类似使用者,通过构造方法注入后,那么就可以使用它

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,518评论 19 139
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 5,016评论 0 2
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,958评论 18 399
  • 学习资料来自 Angular.cn 与 Angular.io。 模板语法 在线例子 在 Angular 中,组件扮...
    小镭Ra阅读 9,228评论 0 3
  • 思路: 1、通过runtime添加两个字符串属性,供外接访问。一个为设置占位字符串(placeholder)使用,...
    逍遥晨旭阅读 5,314评论 6 13