子路由重新加载而不从父路由获取数据
Child route reloading without getting data from parent route
我有一个组件 'panel',它有两个子路线仪表板和假期。
这两个子路由都从父组件服务获取有关其 ngOnInit 的数据。
一切正常,如果我们以正常方式进行,仪表板正在加载数据,但如果我们重新加载子路由,则它不会获取父服务数据。
如何解决这个问题?
路由模块:-
{
path: 'panel',
component: PanelComponent,
canActivate: [AuthGuard],
children: [
{
path: 'dashboard',
component: DashboardComponent,
},
{
path: 'holidays',
component: HolidaysComponent
}
]
}
panelComponent.ts:-
export class PanelComponent implements OnInit {
constructor(private panelService: PanelService, route: ActivatedRoute, private router: Router) {
}
ngOnInit() {
this.panelService.getUserProfile().subscribe(
res => {
this.panelService.userDetails = res;
this.router.navigate(['panel/dashboard'])
},
err => {
console.log(err);
},
);
}
DashboardComponent.ts:-
export class DashboardComponent {
/** dashboard ctor */
private userDetails = {
name:""
}
constructor(private panelService: PanelService) {
}
ngOnInit() {
//console.log(this.panelService.userDetails.profileDetails[0].name);
this.userDetails.name=this.panelService.userDetails.profileDetails[0].name
}
ngOnInit
在创建组件时调用。可能当您第一次访问问题 URL 时,两个组件都被创建了,但是当您再次访问时,只有子组件被创建了,因为父组件从未被销毁过。检查何时为 2 个组件触发 ngOnInit
和 ngOnDestroy
。
您可能需要重构您的代码。
当这些组件为单个路由渲染时,最好在组件之间共享数据。
Everything is working fine
在这种情况下你的子组件会在父组件之后渲染,
但有时你需要从子路由刷新然后你需要从子组件调用服务方法本身。
我认为您需要像下面这样重构您的子组件
ngOnInit() {
if(!this.panelService.userDetails) {
this.panelService.getUserProfile().subscribe( res => {
this.panelService.userDetails = res;
},
err => {
console.log(err);
});
}
this.userDetails.name = this.panelService.userDetails.profileDetails[0].name;
}
编辑
BehaviorSubject
是满足您要求的好方法。但是,如果您重新加载子路由本身,您可能也会丢失 behaviorSubject
项目中的数据。
如果您认为即使是子路由也需要刷新数据,检查子组件中的数据是更好的方法。(至少在我看来是这样)。
你最好在你的服务中使用 BehaviorSubject
并订阅它的 observable,你的服务看起来像:
export class PanelService {
private userDetailsSubject = new BehaviorSubject(null);
userDetails$: Observable<UserDetail> = this.userDetailsSubject.asObservable();
}
然后改变你的getUserProfile
函数
getUserProfile() {
return this.http.get(‘uri-to-server-resource’).pipe(
tap(res => this.userDetailsSubject.next(res))
);
}
还有你的PanelComponent
export class PanelComponent implements OnInit {
constructor(private panelService: PanelService, route: ActivatedRoute, private router: Router) {
}
ngOnInit() {
this.panelService
.getUserProfile().subscribe(
res => {
this.router.navigate(['panel/dashboard'])
},
err => {
console.log(err);
},
);
}
然后您的 DashboardComponent
将订阅服务上的可观察对象
this.panelService.userDetails$.subscribe(value => this.userDetails = value);
或直接在您的模板中使用
{{panelService.userDetails$ | asynchronous}}
我有一个组件 'panel',它有两个子路线仪表板和假期。 这两个子路由都从父组件服务获取有关其 ngOnInit 的数据。
一切正常,如果我们以正常方式进行,仪表板正在加载数据,但如果我们重新加载子路由,则它不会获取父服务数据。
如何解决这个问题?
路由模块:-
{
path: 'panel',
component: PanelComponent,
canActivate: [AuthGuard],
children: [
{
path: 'dashboard',
component: DashboardComponent,
},
{
path: 'holidays',
component: HolidaysComponent
}
]
}
panelComponent.ts:-
export class PanelComponent implements OnInit {
constructor(private panelService: PanelService, route: ActivatedRoute, private router: Router) {
}
ngOnInit() {
this.panelService.getUserProfile().subscribe(
res => {
this.panelService.userDetails = res;
this.router.navigate(['panel/dashboard'])
},
err => {
console.log(err);
},
);
}
DashboardComponent.ts:-
export class DashboardComponent {
/** dashboard ctor */
private userDetails = {
name:""
}
constructor(private panelService: PanelService) {
}
ngOnInit() {
//console.log(this.panelService.userDetails.profileDetails[0].name);
this.userDetails.name=this.panelService.userDetails.profileDetails[0].name
}
ngOnInit
在创建组件时调用。可能当您第一次访问问题 URL 时,两个组件都被创建了,但是当您再次访问时,只有子组件被创建了,因为父组件从未被销毁过。检查何时为 2 个组件触发 ngOnInit
和 ngOnDestroy
。
您可能需要重构您的代码。
当这些组件为单个路由渲染时,最好在组件之间共享数据。
Everything is working fine
在这种情况下你的子组件会在父组件之后渲染, 但有时你需要从子路由刷新然后你需要从子组件调用服务方法本身。
我认为您需要像下面这样重构您的子组件
ngOnInit() {
if(!this.panelService.userDetails) {
this.panelService.getUserProfile().subscribe( res => {
this.panelService.userDetails = res;
},
err => {
console.log(err);
});
}
this.userDetails.name = this.panelService.userDetails.profileDetails[0].name;
}
编辑
BehaviorSubject
是满足您要求的好方法。但是,如果您重新加载子路由本身,您可能也会丢失 behaviorSubject
项目中的数据。
如果您认为即使是子路由也需要刷新数据,检查子组件中的数据是更好的方法。(至少在我看来是这样)。
你最好在你的服务中使用 BehaviorSubject
并订阅它的 observable,你的服务看起来像:
export class PanelService {
private userDetailsSubject = new BehaviorSubject(null);
userDetails$: Observable<UserDetail> = this.userDetailsSubject.asObservable();
}
然后改变你的getUserProfile
函数
getUserProfile() {
return this.http.get(‘uri-to-server-resource’).pipe(
tap(res => this.userDetailsSubject.next(res))
);
}
还有你的PanelComponent
export class PanelComponent implements OnInit {
constructor(private panelService: PanelService, route: ActivatedRoute, private router: Router) {
}
ngOnInit() {
this.panelService
.getUserProfile().subscribe(
res => {
this.router.navigate(['panel/dashboard'])
},
err => {
console.log(err);
},
);
}
然后您的 DashboardComponent
将订阅服务上的可观察对象
this.panelService.userDetails$.subscribe(value => this.userDetails = value);
或直接在您的模板中使用
{{panelService.userDetails$ | asynchronous}}