我有一个MapComponent,它加载一个OpenLayers Map。这个组件被重用在我的Angular应用的各个页面中。
地图第一次加载很好。但是,当我导航到包含该映射的另一个组件时,该映射变为空白。为了再次看到它,我必须导航到不包含映射的组件,然后导航回所需的页面。
我只是在从Angular 8升级到Angular 10之后才观察到这种行为。
Openlayers version 6.5和5.3都存在这个问题。
尝试解决:
-
我已经尝试在我的页面的OnDestroy生命周期钩子中强制设置
this.map = null
。听起来不像是一个好的解决方案,不起作用. -
我已经尝试抛出一个错误在AfterContentInit:
ngAfterContentInit() {
throw new Error("gramschaap");
}
它对页面的呈现有点混乱,当然会留下一个很大的错误,但是可以工作.
- 我已经尝试设置超时,删除并重新设置
ngAfterViewInit
中地图的目标:
ngAfterViewInit() {
this.initMap();
setTimeout(() => {
if (this.map) {
this.map.setTarget(null);
this.map.setTarget("mapTarget");
}
}, 1000);
}
这当然意味着地图在重新绘制之前是空白的;但它工作!
- 我已经尝试将地图目标设置为
ngOnDestroy
不存在的东西。
ngOnDestroy() {
this.map.setTarget("raargitaar"); // does not exist
}
我认为这可能与目标没有第二次初始化有关。但是不起作用.
另一种方法是使用动态映射id作为目标。
我消除了我的问题类似于你的第三次尝试。然而,我给了0超时,而不是给1秒,你不需要setTarget(null)
。
private initMap(): void {
this.map = new Map({...})
setTimeout(() => {
this.map.setTarget('id');
}, 0);
}
我对这个问题感到困惑,并尝试了许多不工作的事情。奇怪的是,如果你把下面这段HTML放在你的主容器之外,map会被渲染,然而,如果你需要把它放在你的容器内,那么地图不会被渲染。
<div id="map"></div>
似乎下面的方法工作,虽然它增加了1秒的延迟加载地图,但我认为这应该是可以容忍的。
ngAfterViewInit() {
this.map = new Map({
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [36.85119033, -1.29393749], /* Coordinates */
zoom: 5
})
});
setTimeout(() => {
if (this.map) {
this.map.setTarget("map");
}
}, 1000);
}
我没有看到原始代码。但我用的是:
我有一个下拉列表,可以在两种地图类型之间切换。我需要重新绘制相应的地图类型,即渲染适当的地图。
我使用BehaviorSubject
作为下拉列表的源:
mapSource$: BehaviorSubject<'google' | 'openlayers'> = new BehaviorSubject<'google' | 'openlayers'>('google');
在我的组件封装了OpenLayers和Google map(其中一个是活动的)的事件中,我对其值变化做出反应:
ngAfterViewInit() {
this.mapSource$.subscribe((mapSource: 'google' | 'openlayers') => {
this.cd.detectChanges();
this.initMap();
});
}
为map.setTarget()添加超时对我来说是最好的解决方案。第二次,您应该将map
变量更新为this.map = new Map({Option})
。
this.map = new Map(mapOptions);
setTimeout(() => {
this.map.setTarget(MAP_TARGET);
this.onMapReady$.next();
}, 100);