问题描述
应用程序
- MapViewComponent
- SearchComponent(需要MapViewComponent的对象)
- MapService
到目前为止,我放置了 SearchComponent
在 MapViewComponent
的模板中,这样我就可以使用 SearchComponent > @Inject(forwardRef(()=> MapViewComponent))。但是由于搜索组件应该显示在布局/ HTML DOM中的其他位置,我想我必须使用服务将 MapViewComponent
传递给搜索。
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))
. 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 - 等待服务变量初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!