3

Я пытаюсь настроить конфигурацию маршрутизатора с помощью Resolve, который возвращает Observable из BehaviorSubject. Я попытался это как в угловом 4.0.0-beta8 и угловой 2.4.8 + маршрутизатор 3.4.8Угловой 2-роутер с использованием BehaviorSubject, наблюдаемый при разрешении

Вот моя служба:

@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() не работает, но издеваемое наблюдение работает.

+0

В чем проблема? «не работает» нет информации. –

ответ

7

Я думал об этом один в течение ночи, и понял, что я использовал решимость неправильно. Суть проблемы в том, что маршрутизатор ожидает, что результат решения будет в конечном итоге завершен . BehaviorSubject, хотя он имеет только одно значение за один раз, никогда не будет сделано, потому что значение всегда может измениться. Я изменил this._data.asObservable() на this._data.asObservable().first(), и он начал работать. Теперь это так очевидно!

+0

hmm, похоже, не работает с угловым 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

Я думаю, я согласен с тем, что это должно быть каким-то образом обработано инфраструктурой, поэтому мне очень интересно посмотреть, что такое обратная связь на ошибке. – SnailCoil

Смежные вопросы