本文介绍了Angular2 - 等待服务变量初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序


  • MapViewComponent

  • SearchComponent(需要MapViewComponent的对象)

  • MapService

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

So far, I placed the SearchComponent inside the MapViewComponents template so I was able to pass it to the SearchComponent by using @Inject(forwardRef(() => MapViewComponent)) . But as the search component should be displayed somewhere else within the layout / HTML DOM, I think I have to use a service to pass the MapViewComponent to the Search.

MapViewComponent.ts:

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:

SearchComponent.ts:

export class SearchComponent {

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

MapService.ts:

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()之前被调用。

It obviously wont work like that, because getView() might get called before setView().

推荐答案

你应该使用( BehaviorSubject ReplaySubject )。 主题将同时充当生产者和消费者。它的消费者可以订阅它,就像一个可观察的。生产者可以使用它向消费者发送消息。例如

You should use a Subject (either BehaviorSubject or ReplaySubject). The Subject will act as both a producer and consumer. The consumer of it can subscribe to it, just like an observable. And the producer can use it to emit messages to consumers. For example

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 ,它将在订阅时自动处理

The MapViewComponent just needs to call the setCurrentView, and it will be handled by the subscribers automatically when it's sent

另见:


  • 有关主题 / BehaviorSubject 之间差异的简要说明/ ReplaySubject

  • This post for a brief description about difference between Subject/BehaviorSubject/ReplaySubject

这篇关于Angular2 - 等待服务变量初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 21:22