2017-02-21 180 views
3

我試圖設置我的路由器配置使用Resolve從行爲主題返回Observable。我已經在這兩個角度4.0.0-beta8和角2.4.8 +路由器試過這種3.4.8Angular 2路由器在Resolve中使用BehaviorSubject Observable

這裏是我的服務:

@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確實有效,我可能會發瘋。

+0

什麼問題? 「不起作用」是沒有信息的。 –

回答

7

我想這一個通宵,並意識到,我用的是決心不正確。問題的關鍵在於路由器期望解析結果最終爲完成。行爲主題,即使它只有一個值時間,將永遠不會完成,因爲該值可以隨時更改。我將this._data.asObservable()更改爲this._data.asObservable().first(),並開始工作。現在看起來很明顯!

+0

嗯,似乎沒有角5,越來越白的屏幕 – Tsar

1

似乎它是一個錯誤。

轉載它在plunker:https://plnkr.co/edit/XmjC2rJ20VQWCsfncVIc?p=preview

@Injectable() 
export class MyService { 
    private _data: BehaviorSubject<Array<string>> = new BehaviorSubject(undefined); 

    constructor() { 
     console.log('created MyService'); 
     console.log(symbolObservable); 
    } 

    public getData(): Observable<Array<string>> { 

     this._data.next(['test1', 'test2', 'test3']); 
     this._data.do(myData => { 
      console.log([myData, 'this console message DOES show up']); 
     }); 

     return this._data.delay(1000); // <-- won't work .. maybe an angular bug !! 
     return Observable.of(['test']); 
    } 
} 

創建在GitHub上的錯誤:https://github.com/angular/angular/issues/14614

+0

我想我同意這應該由框架以某種方式處理,所以我非常有興趣看看有什麼反饋意見在bug上。 – SnailCoil