组件通讯
需要做到组件通讯松耦合性,这样组件的重用性才高
输入属性@Input()
如果一个组件需要从外部接受一些东西,他应该用输入属性声明他需要的东西,至于这些东西从哪里来,组件不需要知道。就像小时候的自己,只知道索取,而获得方式并不了解。
接收父组件信息,被@Input装饰器注解的属性
输入属性是单向的数据传递,只能父组件传递信息给子组件,子组件无法影响父组件
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;
}
输出属性
使用输出属性和EventEmitter对象发射自定义事件,这些事件可以被其他组件处理。
EventEmitter:Rxjs中subject对象的子类,在响应式编程中既可以做观察者,也可做被观察者,可以使用emit()发射事件,也可以使用subscribe()订阅EventEmitter发射出来的事件流。
这里我们 重点讲一下用emit发射事件。
子组件将结果返回给父组件的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;
}
}
中间人模式
用于存在于同一个父组件的A、B两个组件
当B组件需要A组件的输出信息是,A组件发射事件,其父组件接收,然后B组件通过@Input()属性接收父组件信息。