主要包括开发中常用到的:
- 父组件传值给子组件.
- 父组件主动获取子组件中的变量、调用子组件的方法。
- 子组件传值给父组件.
- 通过Service做数据传递
1.父组件传值给子组件
子组件中
@Input() userName:string = '';
@Input() age:string = '';
父组件中
<app-b-page
[index]="i"
[userName]="item.name" >
</app-b-page>
可以在子组件ngOnChanges方法中监听父组件传递进来的数据变化。
2.父组件主动获取子组件中的变量、调用子组件的方法
1.通过模板引用变量
父组件html中
<!--调用子组件的方法-->
<button type="button" (click)="timer.start()">Start</button>
<!--获取子组件的变量 会根据子组件数据的变化实时刷新-->
<div class="seconds">{{timer.seconds}}</div>
<!--使用 # 对组件命名-->
<app-countdown-timer #timer></app-countdown-timer>
2.通过 @ViewChild()
父组件TS代码中:
头文件中添加 ViewChild
import { Component, OnInit, ViewChild } from '@angular/core';
通过@ViewChild属性装饰器,将子组件BPageComponent注入到私有属性bpageComponent里面
@ViewChild(BPageComponent) private bpageComponent!: BPageComponent;
//获取子组件属性
this.bpageComponent.userName;
//调用子组件方法
this.bpageComponent.onSaveScore('', '');
3.子组件传值给父组件
需要通过: @Output()和EventEmitter
方法如下:
子组件中
声明@Output()
@Output() onChangeMathScores:EventEmitter<string> = new EventEmitter<string>();
触发子组件的某一个事件,然后再事件中使用onChangeMathScores。
this.onChangeMathScores.emit(mathScores);
父组件中
TS代码中添加一个接收的方法:
onChildChange(value:string){
console.log('value==', value);
}
html代码中:
<app-b-page (onChangeMathScores)="onChildChange($event)"></app-b-page>
这样子组件每次执行this.onChangeMathScores.emit(mathScores);父组件都会收到一个value。感觉类似于callback。
4.通过Service做数据传递
通过rxjs实现
主要步骤: 1.创建服务 2.注册服务 3.在需要的地方监听服务内的方法调用 4.在需要的地方调用服务内的方法 5.那么可不可以通过callback实现?
首先创建一个服务
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ChangeScoreService {
constructor() { }
private chineseScoreChangeSource = new Subject<{index:number, score:string}>();
chineseScoreChange$ = this.chineseScoreChangeSource.asObservable();
saveChineseScore(value:{index:number, score:string}) {
this.chineseScoreChangeSource.next(value);
}
}
注册服务
在需要使用该服务的最上层组件的.ts代码中注册该服务,切记不可重复注册。应该遵循一个模块使用一个服务的原则(我个人这样认为)。
providers:[ChangeScoreService]
监听服务内方法调用
constructor(private service:ChangeScoreService) {
this.service.chineseScoreChange$.subscribe(
newValue =>{
console.log("监听到数据变化==", newValue);
this.users[newValue.index].chineseScore = Number(newValue.score);
});
}
调用服务内的方法
constructor(private service:ChangeScoreService) {
}
//在需要的时候调用服务内方法触发监听
onSend(){
this.service.saveChineseScore({index:this.index,score:chineseScore});
}
我在想是不是不使用RXjs,在Service中通过callback也能实现数据传递。通过测试确实可行
服务文件中这样写
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ChangeScoreService {
constructor() { }
//定义一个方法变量
tempFunc = function name(params:string) {
}
}
在需要监听的地方
this.service.tempFunc = (temp)=>{
console.log('callback测试', temp);
}
在需要传递参数的地方
this.service.tempFunc('测试通过')
我不知道这种方法有什么弊端。但是通过我测试看来确实代码少了一些,而且使用相对简单。
我还在想既然callback行得通那么我写一个全局的callback,不使用服务,应该可以吧??
确实可以,但是通过查资料发现,Angular中没有真正的“全局变量”。
因为.ts文件都需要引入头文件才能使用里面的方法和变量。这样的话还是通过服务来处理好一点。主要是因为方便管理。