问题描述
我遇到了前端组件无法呈现对BehaviorSubject
的更新的问题,希望有人能指出我的错误来源。我已经阅读了许多有关BehaviorSubject问题的问题,但到目前为止,我还没有找到解决方案。我正在将Angular 8与Ionic 4配合使用。
这是前端体验:第一次导航到该组件时,它不会显示任何projectDetails
。
第二次导航到组件网络,它向我显示了应该第一次显示的projectDetails
。
此“滞后” 会持续进行后续导航
我知道这必须表示我对.next()
的调用在重新初始化之前不会反映在组件中。
我知道this.s.getProject(this.projectId);
在组件加载时工作正常,因为该服务中的console.log('service fetch complete>>>>>>',this.project.getValue()['name']);
根据当前导航报告适当的“项目”。但是我很难理解为什么这些数据仅在下次打开时才传播到组件。
我开始怀疑我在版面方面缺少东西...
服务
import { Injectable} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable,BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class myService {
private API_URL = 'http://xxx.xxxxx.com/endpoint/';
private project: BehaviorSubject<any> = new BehaviorSubject({});
public readonly projectObservable: Observable<Object> = this.project.asObservable();
constructor(private http:HttpClient) { }
getProject(projectID:string ){
console.log('service fetching from>>>>>>>',this.API_URL+projectID);
this.http.get(this.API_URL+projectID).subscribe(
(res) => {
this.project.next(res);
console.log('service fetch complete>>>>>>',this.project.getValue()['name']);
}
);
}
}
组件
import { Component,OnInit,OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { myService } from '../../services/myService.service';
@Component({
selector: 'app-layout',templateUrl: './layout.component.html',styleUrls: ['./layout.component.scss'],})
export class LayoutComponent implements OnInit,OnDestroy {
// Route Paramaters
private projectTitle: string;
private projectId: string;
// Content Object
private projectDetails;
constructor(private route: ActivatedRoute,private s: myService) {
this.route.params.subscribe(routeParams => console.log("layout.component params",routeParams));
}
ngOnInit() {
this.projectTitle = this.route.snapshot.params.projectTitle;
this.projectId = this.route.snapshot.params.projectId;
this.s.getProject(this.projectId);
this.s.projectObservable.subscribe(prj => this.projectDetails = prj);
}
ngOnDestroy() {
console.log('hello - layout component destroyed');
}
}
布局
<ion-card>
<ion-card-header>
<ion-card-subtitle>{{projectDetails.type}}</ion-card-subtitle>
<ion-card-title>{{ projectTitle }}</ion-card-title>
</ion-card-header>
<ion-card-content>
<div markdown ngPreserveWhitespaces>
{{projectDetails.Narrative}}
</div>
</ion-card-content>
</ion-card>
非常感谢您的帮助!
解决方法
一个想法:也许在调用ngOnInit()之前未触发路由订阅,因此该路由尚未包含您要查找的数据。您可以在ngOnInit()中进行配置时订阅您的路由,并在该订阅中执行现在在ngOnInit()中的逻辑
,问题
问题在下面的行this.projectId = this.route.snapshot.params.projectId;
中。首次访问该页面时,angular将加载该组件。当您第二次访问该页面时,angular指出该组件没有任何变化,并重新使用了已加载的组件,因此行为
解决方案
您需要一种在路由器参数更改时触发更改检测的方法。最简单的方法是在注入的paramMap
实例上简单地使用ActivatedRoute
在ngOnInit生命周期挂钩中,将代码替换为
this.route.paramMap.pipe(
map(params => params.get('projectTitle')),tap(projectTitle => this.projectTitle = projectTitle)
).subscribe()
this.route.paramMap.pipe(
map(params => params.get('projectId')),tap(projectId => this.projectId = projectId),tap(projectId => this.s.getProject(this.projectId))
).subscribe()
this.s.projectObservable.subscribe(prj => this.projectDetails = prj);