组件交互,也就是多个组件之间共享信息。
输入类型-父组件传到子组件
可以用输入类型的装饰器@input
来讲子组件的属性标记为是输入类型。
1 | import { Component, OnInit, Input, Output } from '@angular/core'; |
上面的例子中将属性hero
和i
标记为输入属性,表示是从父组件中接收值,其中将属性i
指定了一个别名index
(起别名是不推荐的风格),在html中的使用:
1 | <app-hero-detial *ngFor="let hero of heroes; trackBy: trackByFun; let i = index;" [hero]="hero" [index]="i"> |
通过setter拦截输入属性的变化
使用输入属性的setter,以拦截父组件中的值,并采取一定的措施:
1 | public _hero: Hero; |
上面的例子中创建了组件的私有属性_hero
,然后在标记输入类型的时候使用了setter拦截,用法为:
1 | @Input() set property_name(param: param:type) { |
同时搭配使用取值属性getter,用法为:
1 | get property_name(): property_type{ |
父组件监听子组件的事件
利用EventEmitter
模块的emit
属性来向上“弹射”事件。EventEmitter
模块的作用是:
Use by directives and components to emit custom Events.使用组件和指令来发射自定义事件。
父组件绑定到这个事件属性,并在事件发生时做出回应。
1 | import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; |
使用装饰器@Output
创建输出属性selectHero
。这个属性是EventEmitter
的实例,当调用子组件的方法selectThisHero
的时候,会调用EventEmitter.emit
属性来将参数hero
来“弹射”到父组件。
父组件绑定事件:
1 | <app-hero-detial *ngFor="let hero of heroes; trackBy: trackByFun; let i = index;" [hero]="hero" [i]="i" (selectHero)="selectThisHero($event)"> |
父组件将子组件的selectHero
属性绑定到父组件的selectThisHero
方法,然后父组件可以拿到子组件中选择的hero
的值:
1 | selectThisHero(hero: Hero): void { |
总得来说,就是通过EventEmitter
模块的emit
方法将子组件的事件属性和父组件的事件属性连接起来,达到输出属性的效果。
##子组件和父组件通过引用变量来互动
父组件不能通过数据绑定的方式来读取子组件的属性或调用子组件的方法,但可以在父模板中,使用引用变量来创建本地变量的方式来调用子组件的属性或方法:
1 | <button (click)="heroAbility.walk()">前进 {{hero.name}}</button> |
将子组件声明为引用变量heroAbility
,就可以在父组件中使用通过子组件的引用变量来使用子组件的方法或属性。
注意的是,这种引用变量的方法只能在模板中使用,父组件的类无法读取子组件的属性或变量。
父组件调用@ViewChild()
当父组件的类需要控制子组件的方法或属性时,可以把子组件作为ViewChild
注入到父组件里面。
1 | @ViewChild(HeroAbilityComponent) |