使用BehaviorSubject的Angular 2路由器在解析中可观察到 [英] Angular 2 Router Using BehaviorSubject Observable in Resolve

查看:165
本文介绍了使用BehaviorSubject的Angular 2路由器在解析中可观察到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用一个Resolve来设置我的路由器配置,该Resolve从BehaviorSubject返回一个Observable.我已经在角度4.0.0-beta8和角度2.4.8+路由器3.4.8中都尝试过

I'm trying to set up my router config using a Resolve that returns an Observable from a BehaviorSubject. I've tried this in both angular 4.0.0-beta8 and angular 2.4.8+router 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', 'test2', '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', 'test2', 'test3'],
                        closed: false,
                        hasError: false,
                        isStopped: false,
                        observers: Array[1],
                        thrownError: null,
                        value: ['test1', 'test2', 'test3']
                    }
                }
            },
            Observable {
                _isScalar: false,
                operator: DelayOperator,
                source: ScalarObservable {
                    _isScalar: true,
                    scheduler: null,
                    value: ['test1', 'test2', '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', 'test2', 'test3']
    }
}

这可能不是设计解决方案和服务之间交互的最佳方法,因此我很乐意在那里提出建议.但是,如果我不弄清楚为什么BehaviorSubject.asObservable()不起作用,但模拟的observable起作用,我可能会发疯.

This is probably not the best way of designing the interaction between the resolve and the service, so I'm very open to suggestions there. However, I might go crazy if I don't figure out why BehaviorSubject.asObservable() doesn't work, but the mocked observable does work.

推荐答案

我一整夜都在想这件事,意识到我在错误地使用解析.问题的症结在于路由器希望解析结果最终完成.即使一次只有一个值 ,BehaviorSubject也不会被完成,因为该值可以随时更改.我将this._data.asObservable()更改为this._data.asObservable().first(),它开始工作.现在看来太明显了!

I thought about this one overnight, and realized that I was using the resolve incorrectly. The crux of the problem is that the router expects the resolve result to eventually be completed. The BehaviorSubject, even though it only has one value at a time, will never be done, because the value can always change. I changed this._data.asObservable() to this._data.asObservable().first(), and it started working. It seems so obvious now!

这篇关于使用BehaviorSubject的Angular 2路由器在解析中可观察到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆