今天学习angular的父子组件通信的时候,突然产生一个疑问,出于好奇于是便进行测试分析,在此做下笔记
父组件调用子组件的数据方法的话毋庸置疑我们使用@viewChild更为方便,但是子组件调用父组件事件方法的时候却有两种选择。
1.通过@Input装饰器将父组件事件方法在子组件中接收,之后进行调用
// 父组件html文件
<app-search [showTitle]="showTitle"></app-search>
// 父组件ts文件
export class AppComponent {
public title:any = 'angularTest';
showTitle () {
console.log(this.title);
}
}
// 子组件html文件
<button (click)="showParentTitle()">查看父组件数据</button>
// 子组件ts文件
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
@Input() showTitle: any;
constructor() { }
ngOnInit(): void {}
showParentTitle () {
this.showTitle();
}
}
控制台打印结果:
子组件按钮触发结果为undefind,说明通过@Input方法传入的父组件方法并不是在父组件中调用,而是在子组件中调用,this的作用域为子组件ts文件,换句话说就是拿不到父组件中的任何相关数据,只拿到一个封装的方法
2.通过@Output装饰器与事件发射器 EventEmitter() 监听调用父组件传入的方法
// 父组件html文件
<app-search (showTitle)="showTitle()"></app-search>
// 父组件ts文件
export class AppComponent {
public title:any = 'angularTest';
showTitle () {
console.log(this.title);
}
}
// 子组件html文件
<button (click)="showTitle.emit()">查看父组件数据</button>
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './search.component.html',
styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
@Output() showTitle = new EventEmitter();
public title:any = 'angularTest-search';
constructor() { }
ngOnInit(): void {}
}
控制台打印结果:
此时的打印出来的title值为父组件title,说明@output + EventEmitter这种调用方式this的作用域为父组件ts文件
总结:
那么我们实际应用这两个方法的话应如何做取舍呢
1.当你需要的是仅仅是将父组件所封装的方法拿到子组件进行使用或者操作全局数据例如localStroage的时候,那么@Input会显得更加方便
2.当你需要的是在父组件中操作父组件的数据或其他方法的时候,那么这时你便需要使用到@Output + EventEmitter了
angular所做笔记,如有不对,还望指正