组件通讯
需要做到组件通讯松耦合性,这样组件的重用性才高
父子组件通讯
输入 @Input()
接收父组件信息,被@Input装饰器注解的属性
输出 @Output()
将自身信息告知父组件,被@Output装饰器注解,使用Rxjs中的EventEmitter发射事件
输入属性demo
写一个从父组件接收信息的demo
子组件
//html
<p>
我是子组件,我要从父组件接收信息:{{keyWord}}
</p>
//ts
export class ChildComponent implements OnInit {
@Input()
private keyWord:string; //keyWord用来接收父组件信息
constructor() { }
ngOnInit() {
}
}
父组件
//html
<input [(ngModel)]="ParentKeyWord">
<app-child [keyWord]="ParentKeyWord"></app-child> <!-- 方括号表示输入属性的值 -->
//ts
export class AppComponent {
ParentKeyWord:string;
}
- 在子组件中定义要接收信息的变量
@Input() keyword:string
- 在父html中相关的子标签接收父组件的信息
[keyword]="ParentKeyWord"
- 可以使用
@Input('key') keyword:string
,将输入属性的变量改名为key
Tips:输入属性是单向的数据传递,只能父组件传递信息给子组件,子组件无法影响父组件
输出属性demo
之前在数据绑定时写过内置事件绑定,现在写一下自定义事件的发射。使用输出属性和EventEmitter对象发射自定义事件,这些事件可以被其他组件处理。
EventEmitter:Rxjs中subject对象的子类,在响应式编程中既可以做观察者,也可做被观察者,可以使用emit()发射事件,也可以使用subscribe()订阅EventEmitter发射出来的事件流
子组件将结果返回给父组件的demo
子组件
//html:
<p>
我是子组件,我要从父组件接收信息:{{keyWord}},价格是{{price}}
</p>
//ts:
import { Component, OnInit ,Input ,Output ,EventEmitter} from '@angular/core';
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
@Input()
private keyWord:string;
private price:number;
@Output()
searchResult:EventEmitter<StockInfo> = new EventEmitter();
//格式:EventEmitter<要发射的事件类型>,使用EventEmitter对象,因为其emit方法可以用来发射数据
constructor() { }
ngOnInit() {
setInterval(()=>{
//查询出现的股票信息
let stockInfo:StockInfo = new StockInfo(this.keyWord,100*Math.random());
//查询股票价格,绑定在html上
this.price = stockInfo.price;
//将股票信息发射出去
this.searchResult.emit(stockInfo);
},3000);
}
}
export class StockInfo{
constructor(public name:string,public price:number){
}
}
父组件:
//html:
<div>
<app-child [keyWord]="ParentKeyWord" (searchResult)="searchResultHandle($event)"></app-child>
价格是{{currentPrice}}
</div>
<!-- (searchResult)自定义的发射事件,等号右侧用searchResultHandle方法处理发射出来的事件 -->
//ts
export class AppComponent {
ParentKeyWord:string;
currentPrice:number;
searchResultHandle(stockInfo){
this.currentPrice = stockInfo.price;
}
}
- 子组件查询到相关股票信息后
- 使用@Output()输出属性和EventEmitter对象声明事件searchResult
- 使用emit()方法发射股票信息出去
- 在父组件接收并处理事件
- 可以使用
@Output('mysearchResult')
,将输出属性的变量改名
Tips:EventEmitter对象来自@angular/core
输出属性命名规则
child.component.ts:
@Input() rating:number;
@Output() ratingChange:EventEmitter<number> = new EventEmitter();
//这样的命名规则可以使rating进行双向数据绑定
father.component.html
<app-stars [(rating)]="stock.rating"></app-stars>
中间人模式
第一种情况:用于A和B组件都有的父组件
当B组件需要A组件的输出信息时,A组件发射事件,其父组件接收,然后B组件通过@Input()属性接收父组件信息。