无法在 Angular 5 中的孙组件之间共享 Observable Subject 服务
Unable to share Observable Subject service between grandchildren components in Angular 5
我有一个应用程序,我正在使用 angular cdk 步进器,我试图在两个 child 步骤中的公共 grandchild 组件之间共享数据组件。
第一个 child 传递数据来填充 grandchild,但问题似乎是步进器同时初始化了两个组件,并且由于第一个 child 必须调用服务来填充 grandchild,第二个 child 的 child 使用不完整的数据进行初始化。
parent.component.html:
<app-custom-stepper>
<cdk-step [stepControl]="frmStep1" #step1="cdkStep">
<ng-template cdkStepLabel>Step1</ng-template>
<form #frmStep1="ngForm">
<child1 [myData]="myData"></child1>
</form>
<button cdkStepperPrevious>Prev</button>
<button cdkStepperNext>Next</button>
</cdk-step>
<cdk-step cdkStep #step2="cdkStep">
<form #frmStep2="ngForm">
<child2></child>
</form>
<button cdkStepperPrevious>Prev</button>
<button cdkStepperNext>Next</button>
</cdk-step>
parent.service.ts
export class ParentService {
myData:Subject<any> = new Subject<any>();
setMyData(data: any) {
this.myData.next(data);
}
getMyData(): Observable<any> {
return this.myData.asObservable();
}
}
child1.component.html:
<sharedGrandchild [myData]="myData"></sharedGrandchild>
child2.component.html
<sharedGrandchild></sharedGrandchild>
grandchild.component.ts:
@Input() myData:MyData;
ngOnInit() {
if(this.myData) {
//call service that populates data, this only happens on the page
//step of the stepper
this.parentService.setMyData(response);
} else {
this.parentService.getMyData()
.subscribe( myData => {
this.myData = myData
}
};
我尝试过的事情:
使用 BehaviorSubjects 和 Subjects(如上面的代码)
使用开关延迟第二个 child 组件的初始化
尝试使用其他生命周期挂钩来初始化第二个 childs 组件的订阅。
问题是时间问题,请求第一个 child 通过 grandchild 触发需要很长时间才能 return,所以 grandchild 出现在第二个child 正在订阅仅部分存在的 object。这似乎永远不会更新。因此,页面上的第一个 child 加载正常,因为它直接访问服务,步进器第二页上的第二个 child 由于同时初始化,因此数据不完整。
您应该遵循以下步骤以确保异步共享数据-
1.Use BehaviorSubject
存储最后的设定值。
myData:Subject<any> = new BehaviorSubject<any>(null);
2.Read 并在函数 ngAfterViewInit
中设置数据而不是 ngOnInit
@Input() myData:MyData;
ngAfterViewInit() {
if(this.myData) {
//call service that populates data, this only happens on the page
//step of the stepper
this.parentService.setMyData(response);
} else {
this.parentService.getMyData()
.subscribe( myData => {
this.myData = myData
}
};
3.Ensure ParentService
是在公共模块或主模块或根模块中提供的
我有一个应用程序,我正在使用 angular cdk 步进器,我试图在两个 child 步骤中的公共 grandchild 组件之间共享数据组件。
第一个 child 传递数据来填充 grandchild,但问题似乎是步进器同时初始化了两个组件,并且由于第一个 child 必须调用服务来填充 grandchild,第二个 child 的 child 使用不完整的数据进行初始化。
parent.component.html:
<app-custom-stepper>
<cdk-step [stepControl]="frmStep1" #step1="cdkStep">
<ng-template cdkStepLabel>Step1</ng-template>
<form #frmStep1="ngForm">
<child1 [myData]="myData"></child1>
</form>
<button cdkStepperPrevious>Prev</button>
<button cdkStepperNext>Next</button>
</cdk-step>
<cdk-step cdkStep #step2="cdkStep">
<form #frmStep2="ngForm">
<child2></child>
</form>
<button cdkStepperPrevious>Prev</button>
<button cdkStepperNext>Next</button>
</cdk-step>
parent.service.ts
export class ParentService {
myData:Subject<any> = new Subject<any>();
setMyData(data: any) {
this.myData.next(data);
}
getMyData(): Observable<any> {
return this.myData.asObservable();
}
}
child1.component.html:
<sharedGrandchild [myData]="myData"></sharedGrandchild>
child2.component.html
<sharedGrandchild></sharedGrandchild>
grandchild.component.ts:
@Input() myData:MyData;
ngOnInit() {
if(this.myData) {
//call service that populates data, this only happens on the page
//step of the stepper
this.parentService.setMyData(response);
} else {
this.parentService.getMyData()
.subscribe( myData => {
this.myData = myData
}
};
我尝试过的事情:
使用 BehaviorSubjects 和 Subjects(如上面的代码) 使用开关延迟第二个 child 组件的初始化 尝试使用其他生命周期挂钩来初始化第二个 childs 组件的订阅。
问题是时间问题,请求第一个 child 通过 grandchild 触发需要很长时间才能 return,所以 grandchild 出现在第二个child 正在订阅仅部分存在的 object。这似乎永远不会更新。因此,页面上的第一个 child 加载正常,因为它直接访问服务,步进器第二页上的第二个 child 由于同时初始化,因此数据不完整。
您应该遵循以下步骤以确保异步共享数据-
1.Use BehaviorSubject
存储最后的设定值。
myData:Subject<any> = new BehaviorSubject<any>(null);
2.Read 并在函数 ngAfterViewInit
中设置数据而不是 ngOnInit
@Input() myData:MyData;
ngAfterViewInit() {
if(this.myData) {
//call service that populates data, this only happens on the page
//step of the stepper
this.parentService.setMyData(response);
} else {
this.parentService.getMyData()
.subscribe( myData => {
this.myData = myData
}
};
3.Ensure ParentService
是在公共模块或主模块或根模块中提供的