【问题标题】:Angular2 - Waiting for service variable to be initializedAngular2 - 等待服务变量被初始化
【发布时间】:2016-11-08 00:18:00
【问题描述】:

应用

  • 地图视图组件
  • SearchComponent(需要 MapViewComponent 的对象)
  • 地图服务

到目前为止,我将SearchComponent 放在MapViewComponents 模板中,这样我就可以使用@Inject(forwardRef(() => MapViewComponent)) 将它传递给SearchComponent。但由于搜索组件应该显示在布局/HTML DOM 中的其他位置,我想我必须使用服务将 MapViewComponent 传递给搜索。

MapViewComponent.ts:

export class MapViewComponent {
    @Output() onMapViewCreated = new EventEmitter();

    private _view: any = null;      

    constructor(private mapService: MapService, private elRef: ElementRef) {
    }          

    ngOnInit() {
        this._view = new MapView({
            container: this.elRef.nativeElement.firstChild,
            map: this._mapService.map,
            center: [5.44, 36.947974],
            rotation: 0,
            autoResize: true
        })

        this._view.then((view) => {
            this.onMapViewCreated.next(view);
            this._mapService.setView(view);
        });

SearchComponent.ts:

export class SearchComponent {

    constructor(private elRef:ElementRef, private mapService: MapService ) {
       var view = mapService.getView();
    }
}

MapService.ts:

@Injectable()
export class MapService {
     public setView(mv: MapView){
        this.view = mv;    // what do I have to do here..?
     }  

     public getView(){
        return this.view;  // .. and here?
     }
}

它显然不会那样工作,因为getView() 可能会在setView() 之前被调用。

【问题讨论】:

  • 您应该将Observable<MapView>Promise<MapView> 存储为视图,然后您将在getter 中返回Observable/promise,这允许您执行getView().then(your function...) 并解决您的promise/emit设置视图后,在您的 observable 中。编辑:什么是 MapView?

标签: javascript angular typescript


【解决方案1】:

您应该使用SubjectBehaviorSubjectReplaySubject)。 Subject 将充当生产者和消费者。它的消费者可以订阅它,就像一个可观察的。生产者可以使用它向消费者发送消息。例如

import { ReplaySubject } from 'rxjs/ReplaySubject'

@Injectable()
export class MapService {

  private _currentMapView = new ReplaySubject<MayView>(1);

  setCurrentView(mv: MapView){
    this._currentView.next(mv);
  }

  get currentMapView$() {
    return this._currentMapView.asObservable();
  }
}

订阅者只需订阅

import { Subscription } from 'rxjs/Subscription';

export class SearchComponent {
  sub: Subscription;
  view: MapView;

  constructor(private elRef:ElementRef, private mapService: MapService ) {
  }

  ngOnInit() {
    this.sub = this.mapService.currentMapView$.subscribe(view => {
      this.view = view;
    })
  }

  ngOnDestroy() {
    if (this.sub) {
      this.sub.unsubscribe();
    }
  }
}

MapViewComponent只需调用setCurrentView,发送时订阅者会自动处理

另请参阅:

  • This post简要说明Subject/BehaviorSubject/ReplaySubject之间的区别

【讨论】:

    猜你喜欢
    • 2016-07-27
    • 2023-03-26
    • 2019-03-27
    • 1970-01-01
    • 2018-07-05
    • 2019-04-23
    • 1970-01-01
    • 2023-03-30
    • 2018-12-15
    相关资源
    最近更新 更多