我没有在使用BehaviorSubject的组件中获得响应的值。我得到了它并在服务中传递它。
我在路由保护上从服务中触发HTTP。
服务:
@Injectable()
export class ProjectsService {
projects: Subject<Project[]> = new BehaviorSubject<Project[]>([]);
load(clientId: string, active: boolean): Observable<boolean> {
return new Observable<boolean>((obs) => {
this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId).subscribe(
res => {
let temp = [];
res.forEach(a => temp.push(new Project(a)));
if (active) this.projects.next(temp);
else this.externalProjects.next(temp);
obs.next(true);
obs.complete();
},
err => {
obs.next(false);
obs.complete();
}
);
});
}
成分:
ngOnInit(): void {
// todo: check why not to load already added
this._projectsListener = this._projectsService.projects.subscribe(a => {
this.showIntro = a.length ? false : true;
this.projects = a;
});
}
HTML:
<div class="project" [hidden]="!showIntro" *ngFor="let project of projects>
{{project.title}}
</div>
它只是为HTTP参数设置查询参数... 后卫:
@Injectable()
export class ProjectsGuard implements CanActivate {
constructor(
private _projectsService: ProjectsService,
private _router: Router) {}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
return this._projectsService.load(next.params['id'], true)
}
}
我也尝试NgZone
,但我不确定它是否正确:
load(clientId: string, active: boolean): Observable<boolean> {
return this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId)
.map(res => {
let temp = res.map(a => new Project(a));
this._ngZone.run(() => {
console.log('temp: ', temp);
if (active) this.projects.next(temp);
else this.externalProjects.next(temp);
});
return true;
})
.catch(() => Observable.of(false));
}
答案 0 :(得分:2)
首先:不要在观察者中订阅另一个观察者。相反,将其写为流:
@Injectable()
export class ProjectsService {
projects: Subject<Project[]> = new BehaviorSubject<Project[]>([]);
load(clientId: string, active: boolean): Observable<boolean> {
return this._api.send(active ? 'projects.getActive' : 'projects.getAll',clientId)
.map(res => {
let temp = res.map(a => new Project(a));
if (active) {
this.projects.next(temp);
} else {
this.externalProjects.next(temp);
}
return true;
})
.catch(() => Observable.of(false));
}
其次:不要手动订阅无休止的流来将结果写入类成员,而是使用async
- 管道:
public projects$: Observable<Project[]> = this._projectsService.projects;
public showIntro$: Observable<boolean> = this.projects$
.map(projects => projects.length > 0);
ngOnInit(): void {
// ...nothing to do here
}
模板:
<div class="project" [hidden]="!showIntro" *ngFor="let project of (projects$ | async)>
{{project.title}}
</div>
....somewhere else:
<div *ngIf="showIntro$ | async">INTRO!</div>
如果您的加载问题仍然存在,那么您可能希望共享api.send
方法的内容(除非确实调用它)。
一种可能性是使用在ngZone之外运行的异步方法,然后您可能需要尝试以下操作:
NgZone
(来自&#34; @ angular / core&#34;)this._api.send
内 - 在ngZone.run