Angular 2路由器在Resolve中使用BehaviorSubject Observable

前端之家收集整理的这篇文章主要介绍了Angular 2路由器在Resolve中使用BehaviorSubject Observable前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试使用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(),它开始工作.现在看起来很明显!

猜你在找的Angularjs相关文章