我正在尝试使用Resolve设置我的路由器配置,它从BehaviorSubject返回一个Observable.我在角4.0.0-beta8和角2.4.8路由器3.4.8中尝试了这个
这是我的服务:
@Injectable() export class MyService { private _data: BehaviorSubject<Array<string>> = new BehaviorSubject(undefined); constructor() {} public getData(): Observable<Array<string>> { this._data.next(['test1','test2','test3']); let asObservable = this._data.asObservable().delay(1000); asObservable.subscribe((myData) => { console.log([myData,'this console message DOES show up']); }); // if I return here,my component's constructor and ngOnInit never fire // return asObservable; let fakeObservable = Observable.of(['test1','test3']).delay(1000); fakeObservable.subscribe((fakeData) => { console.log([fakeData,'this console message shows up']); }); console.log([asObservable,fakeObservable]); /* console log output Observable { _isScalar: false,operator: DelayOperator,source: Observable { _isScalar: false,source: BehaviorSubject { _isScalar: false,_value: ['test1','test3'],closed: false,hasError: false,isStopped: false,observers: Array[1],thrownError: null,value: ['test1','test3'] } } },Observable { _isScalar: false,source: ScalarObservable { _isScalar: true,scheduler: null,'test3'] } } */ return fakeObservable; // this WILL reach my component constructor and ngOnInit } }
这是我的决心
@Injectable() export class MyResolver implements Resolve<Array<string>> { constructor(private myService: MyService) {} resolve(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): Observable<Array<string>>|undefined { return this.myService.getData(); } }
这是路由器
RouterModule.forChild([{ path: 'mypath',component: MyComponent,resolve: { data: MyResolver } }]);
这是组件:
@Component({ selector: 'my-component',template: '<Span>My Component</span>' }) export class MyComponent implements OnInit { constructor(private route: ActivatedRoute) { console.log('component constructor'); } ngOnInit(): void { console.log(this.route.snapshot.data['data']); // ['test1','test3'] } }
这可能不是设计解决方案和服务之间交互的最佳方式,因此我对那里的建议非常开放.但是,如果我不弄清楚为什么BehaviorSubject.asObservable()不起作用,我可能会发疯,但模拟的observable确实有效.
解决方法
我一夜之间想到了这一点,并意识到我正在使用解决方法.问题的关键在于路由器期望最终完成解析结果.尽管BehaviorSubject一次只有一个值,但它永远不会完成,因为该值总是可以改变.我将this._data.asObservable()更改为this._data.asObservable().first(),它开始工作.现在看起来很明显!