简体   繁体   English

Angular2-等待服务变量被初始化

[英]Angular2 - Waiting for service variable to be initialized

Application 应用

  • MapViewComponent MapViewComponent
  • SearchComponent (requires an object of the MapViewComponent) SearchComponent(需要MapViewComponent的对象)
  • MapService MapService

So far, I placed the SearchComponent inside the MapViewComponent s template so I was able to pass it to the SearchComponent by using @Inject(forwardRef(() => MapViewComponent)) . 到目前为止,我将SearchComponent放置在MapViewComponent的模板中,因此可以使用@Inject(forwardRef(() => MapViewComponent))将其传递给SearchComponent 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. 但是由于搜索组件应该显示在布局/ HTML DOM内的其他位置,我想我必须使用一项服务来将MapViewComponent传递给搜索。

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?
     }
}

It obviously wont work like that, because getView() might get called before setView() . 它显然不会那样工作,因为getView()可能在setView()之前被调用。

You should use a Subject (either BehaviorSubject or ReplaySubject ). 您应该使用一个SubjectBehaviorSubjectReplaySubject )。 The Subject will act as both a producer and consumer. Subject将同时充当生产者和消费者。 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();
  }
}

The subscriber just needs to suscribe 订户只需要订阅

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();
    }
  }
}

The MapViewComponent just needs to call the setCurrentView , and it will be handled by the subscribers automatically when it's sent MapViewComponent只需调用setCurrentView ,它就会在发送时由订阅者自动处理。

See Also: 也可以看看:

  • This post for a brief description about difference between Subject / BehaviorSubject / ReplaySubject 这篇文章简要介绍了Subject / BehaviorSubject / ReplaySubject之间的ReplaySubject

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM