Angular4学习笔记——组件之间的交互

经过输入型绑定把数据从父组件传到子组件

Angular对于父组件 => 子组件的数据通讯作法和Vue很类似。html

// 父组件html模板
<app-hero-child *ngFor="let hero of heroes"
      [hero]="hero"
      [master]="master">
    </app-hero-child>
// 子组件接收数据
import { Component, Input } from '@angular/core';
import { Hero } from './hero';

export class HeroChildComponent {
  @Input() hero: Hero;
  @Input('master') masterName: string;
}
// 第二个@Input为子组件的属性名masterName指定一个别名master,可是这个作法并不推荐

看着是否是很眼熟,写代码的逻辑和Vue几乎能够说是同样了,只是写法上略有区别而已。 前端

这个问题下还有两个截听输入属性值变化的方法,代码逻辑不难推,可是其中的应用场景方面我还没想到是怎么样的,以后也许继续看Angular文档会理解的更透彻一些,届时再来补充啦~~app

父组件监听子组件的事件

这个操做方法也和Vue中的作法很是接近,并且在上一篇笔记中也有所说起。
具体思路:子组件暴露一个EventEmitter属性,当事件发生时,子组件利用该属性emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时做出回应。
还有,子组件的EventEmitter属性是一个输出属性,一般带有@Output装饰器,比较完整的示例以下:函数

// 子组件:先在本身的组件中触发了vote方法,而后在vote方法中向父组件发出onVoted事件,同时传送一个payload(agreed)
// 在Vue中的写法是this.$emit(onVoted,agreed)
import { Component, EventEmitter, Input, Output } from '@angular/core';

export class VoterComponent {
  @Input()  name: string;
  @Output() onVoted = new EventEmitter<boolean>();
  voted = false;
 
  vote(agreed: boolean) {
    this.onVoted.emit(agreed);
    this.voted = true;
  }
}
// 父组件:监听onVoted事件,若是监听到了则触发本身组件中的agree方法,同时经过$event把payload传参给agree
html:
<app-voter (onVoted)="onVoted($event)"></app-voter>
ts:
export class VoteTakerComponent {
  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}

父子组件的其余互动关系

父组件与子组件经过本地变量互动

父组件对子组件的数据绑定属于单向绑定,子组件没法直接把数据、属性和自身的方法传送给父组件使用。尽管有EventEmitter属性,可是有时候须要直接访问子组件的内容,用这种方法并不合适。this

// 能够在父组件的模板中直接访问子组件的全部属性和方法,例如此例即是直接访问了子组件的start(),stop()方法和seconds属性
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div class="seconds">{{timer.seconds}}</div>
<app-countdown-timer #timer></app-countdown-timer>

父组件调用@ViewChild()

上述方法有必定局限性:父组件-子组件的链接必须所有在父组件的模板中进行。父组件自己的代码对子组件没有访问权。若是想要在代码中直接访问子组件的内容,可使用这个方法把子组件做为ViewChild,注入到父组件里面,具体操做以下:code

// 须要经过@ViewChild属性装饰器,将子组件CountdownTimerComponent注入到私有属性timerComponent里面,并挂在AfterViewInit生命周期钩子里
export class CountdownViewChildParentComponent implements AfterViewInit {
// 在父组件中将子组件注册为变量timerComponent,记得在括号里写明子组件名字~~ 
  @ViewChild(CountdownTimerComponent)  private timerComponent: CountdownTimerComponent;
// 这样就能够经过this.timerComponent访问子组件的内容了
  start() { this.timerComponent.start(); }
  stop() { this.timerComponent.stop(); }
}

经过服务来通信

父组件和它的子组件(们)共享同一个服务,利用该服务在父子组件之间实现双向通信。
该服务实例的做用域被限制在父组件和其子组件(们)内。这个组件子树以外的组件将没法访问该服务或者与它们通信。htm

父子组件经过各自的构造函数注入该服务。文档中的例子还须要一些额外知识才能明白,以后再分析啦!~生命周期

前端新人,写的不对的地方还请指出;
若是以为对你有帮助,能够点个赞鼓励一下我哦!~~事件

相关文章
相关标签/搜索