Parent 到 child 通信无法使用 Angular 9 mat-tab
Parent to child communication not working with Angular 9 mat-tab
我对 Angular 比较陌生。我试图使用 @Input() 将数据从 parent 组件传递到 child 组件,但未反映更改。
我有一个带有 select 元素的 parent 组件,我想将 selected 项的值传递给 children。
parent 组件有一个 mat-tab-group 和一些 mat-tab(s)。
Parent HTML
<mat-form-field>
<mat-select placeholder="Class" [formControl]="selectedClassControl" (selectionChange)="changeClassId()">
<mat-option *ngFor="let class of classes" value="{{class.id}}">{{class.classNumber}}-{{class.section}}</mat-option>
</mat-select>
</mat-form-field>
<mat-tab-group color="primary" (selectedIndexChange)="selectTab($event)">
<mat-tab label="Units">
<app-units [classId]="classId" *ngIf="selectedTab === 0"></app-units>
</mat-tab>
<!-- many such tabs with the same structure -->
</mat-tab-group>
Parent TS
classId : number = 0;
classes: Class[];
selectedClass: any;
selectedClassControl = new FormControl(this.selectedClass);
constructor(private classService: ClassService, private stateMgmtService:
StateManagementService) {
var schoolId = this.stateMgmtService.getSchoolId();
this.classService.getClasses(schoolId).subscribe(data =>{
this.classes = data;
})
}
selectedTab = 0;
ngOnInit(): void {
}
selectTab(event) {
this.selectedTab = event;
}
changeClassId(){
this.classId = this.selectedClassControl.value;
console.log("ClassId changed to "+this.classId);
}
Child HTML
<mat-form-field>
<mat-select placeholder="Subject" [formControl]="selectedSubjectControl" >
<mat-option *ngFor="let subject of subjects" value="{{subject.id}}">{{subject.code}}-{{subject.name}}</mat-option>
</mat-select>
</mat-form-field>
Child TS
@Input() classId : number = 0;
subjects: Subject[];
selectedSubject: any;
selectedSubjectControl = new FormControl(this.selectedSubject);
constructor(private classService: ClassService) {
console.log("classId"+this.classId);
if(this.classId != 0)
classService.getSubjects(this.classId).subscribe( data => {
this.subjects = data;
})
}
我看到的是,当我在 parent 组件中更改我的 selection 时,classId 没有传达给 child 组件,我应该手动刷新组件吗?要反映的更改?
非常感谢任何帮助...
TIA
对于输入变量,构造函数可能过早触发。您可以尝试使用 OnChanges
挂钩手动监听输入变量的变化。尝试以下
import { Component, Input, OnChanges } from "@angular/core";
export class ChildComponent implements OnChanges {
@Input() classId: number = 0;
subjects: Subject[];
selectedSubject: any;
selectedSubjectControl = new FormControl(this.selectedSubject);
constructor(private classService: ClassService) { }
ngOnChanges() {
console.log("classId" + this.classId);
if(this.classId != 0) {
this.classService.getSubjects(this.classId).subscribe( data => {
this.subjects = data;
});
}
}
private doSomething(input: string) {}
}
这里有几件事。首先要小心使用 Subject 作为 class 名称 Subject 是 rxjs 中的一个对象,您可能会不小心导入它。我会让你的 class 名字更具体。
接下来您真的不需要 selectionChange 事件逻辑。相反,您可以订阅表单控件的 valueChanged 属性 并设置 classId 变量,只要它像这样
this.selectedClassControl.valueChanges.subscribe(e => this.classId = e),
接下来在您的子组件中,classId 将更新,但您的主题数组不会
我会像这样在您的输入中使用 setter
@Input() set classId(val: number) {
this._classId = val;
if(val != 0) {
classService.getSubjects(val).subscribe( data => {
this.subjects = data;
}); //assuming this is an http service so no unsubscribe is required
}
}
private _classId: number = 0;
我对 Angular 比较陌生。我试图使用 @Input() 将数据从 parent 组件传递到 child 组件,但未反映更改。 我有一个带有 select 元素的 parent 组件,我想将 selected 项的值传递给 children。 parent 组件有一个 mat-tab-group 和一些 mat-tab(s)。
Parent HTML
<mat-form-field>
<mat-select placeholder="Class" [formControl]="selectedClassControl" (selectionChange)="changeClassId()">
<mat-option *ngFor="let class of classes" value="{{class.id}}">{{class.classNumber}}-{{class.section}}</mat-option>
</mat-select>
</mat-form-field>
<mat-tab-group color="primary" (selectedIndexChange)="selectTab($event)">
<mat-tab label="Units">
<app-units [classId]="classId" *ngIf="selectedTab === 0"></app-units>
</mat-tab>
<!-- many such tabs with the same structure -->
</mat-tab-group>
Parent TS
classId : number = 0;
classes: Class[];
selectedClass: any;
selectedClassControl = new FormControl(this.selectedClass);
constructor(private classService: ClassService, private stateMgmtService:
StateManagementService) {
var schoolId = this.stateMgmtService.getSchoolId();
this.classService.getClasses(schoolId).subscribe(data =>{
this.classes = data;
})
}
selectedTab = 0;
ngOnInit(): void {
}
selectTab(event) {
this.selectedTab = event;
}
changeClassId(){
this.classId = this.selectedClassControl.value;
console.log("ClassId changed to "+this.classId);
}
Child HTML
<mat-form-field>
<mat-select placeholder="Subject" [formControl]="selectedSubjectControl" >
<mat-option *ngFor="let subject of subjects" value="{{subject.id}}">{{subject.code}}-{{subject.name}}</mat-option>
</mat-select>
</mat-form-field>
Child TS
@Input() classId : number = 0;
subjects: Subject[];
selectedSubject: any;
selectedSubjectControl = new FormControl(this.selectedSubject);
constructor(private classService: ClassService) {
console.log("classId"+this.classId);
if(this.classId != 0)
classService.getSubjects(this.classId).subscribe( data => {
this.subjects = data;
})
}
我看到的是,当我在 parent 组件中更改我的 selection 时,classId 没有传达给 child 组件,我应该手动刷新组件吗?要反映的更改?
非常感谢任何帮助...
TIA
对于输入变量,构造函数可能过早触发。您可以尝试使用 OnChanges
挂钩手动监听输入变量的变化。尝试以下
import { Component, Input, OnChanges } from "@angular/core";
export class ChildComponent implements OnChanges {
@Input() classId: number = 0;
subjects: Subject[];
selectedSubject: any;
selectedSubjectControl = new FormControl(this.selectedSubject);
constructor(private classService: ClassService) { }
ngOnChanges() {
console.log("classId" + this.classId);
if(this.classId != 0) {
this.classService.getSubjects(this.classId).subscribe( data => {
this.subjects = data;
});
}
}
private doSomething(input: string) {}
}
这里有几件事。首先要小心使用 Subject 作为 class 名称 Subject 是 rxjs 中的一个对象,您可能会不小心导入它。我会让你的 class 名字更具体。
接下来您真的不需要 selectionChange 事件逻辑。相反,您可以订阅表单控件的 valueChanged 属性 并设置 classId 变量,只要它像这样
this.selectedClassControl.valueChanges.subscribe(e => this.classId = e),
接下来在您的子组件中,classId 将更新,但您的主题数组不会
我会像这样在您的输入中使用 setter
@Input() set classId(val: number) {
this._classId = val;
if(val != 0) {
classService.getSubjects(val).subscribe( data => {
this.subjects = data;
}); //assuming this is an http service so no unsubscribe is required
}
}
private _classId: number = 0;