我正在创建需要通过按钮和滑块支持大量交互性的MapboxGL地图。使用RxJS在另一个序列之后运行序列
MapboxGL地图实例是状态并有气质生命周期由于大量的砖和来源的异步装载。这意味着大部分工作都是在事件处理程序内完成的。这让我认为RxJS是管理所有这些交互性的可靠选择。
例如,如果要将要素图层添加到地图,则the mapbox example建议在map.on('load', handler)
中执行所有操作。这对于静态地图来说很好,但对于具有20多个切换/滑块/控件的地图来说,协调命令式事件处理程序是一件麻烦事。
我想要做的是为每个单独的操作创建序列。其中最基本的是加载地图,然后在地图加载后添加基础要素图层。
所以这里是我得到的,我一直在使用RxJS约5小时总计,所以也许有一些我只是不知道我不知道。
段:
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v9',
center: [-122.78, 38.43],
zoom: 10
});
// Check every 100ms if the map is loaded, if so emit
var loaded$ = Rx.Observable
.interval(100)
.map(() => map.loaded())
.filter(x => x)
.first();
// We must wait until the map is loaded before attaching the feature layer.
var addLayer = loaded$.subscribe(
baseMapLoaded, errorHandler, addFeatureLayerAndSource
);
// Attaching the feature layer sets the map.loaded() to false
// while it fetches the tiles.
//
// When the feature layer and source are loaded,
// log 'all tiles loaded' then 'completed' to the console
//
// Why can I declare `addLayer` and `completed` like this?
// Shouldn't these both fire after the loaded$ emits the first time,
// causing an error?
var completed = loaded$.subscribe(tilesLoaded, errorHandler, completeHandler);
/* Misc Handlers */
function addFeatureLayerAndSource() {
console.log(2, 'adding feature layer and source');
map.addSource('parcel_data', {
'type': 'vector',
'tiles': ['http://localhost:5000/api/v1/tiles/{z}/{x}/{y}']
});
map.addLayer({
"id": "parcel_data",
"type": "fill",
"source": "parcel_data",
"source-layer": "parcel_data",
});
}
function baseMapLoaded() { console.log(1, 'base map loaded'); }
function tilesLoaded() { console.log(3, 'all tiles loaded'); }
function errorHandler(err) { console.log('error handling', err); }
function completeHandler() { console.log('completed'); }
编辑:更新的代码段,以反映@ CalvinBeldin的帮助。目前试图找出为什么这实际上起作用。我console.logs的顺序是正确的:
1 "base map loaded"
2 "adding feature layer and source"
3 "all tiles loaded"
completed
感谢您的帮助!根据MapboxGL问题跟踪器,知道最后一次呈现事件何时开始的唯一方法是检查'render'事件处理程序中是否存在'map.loaded()=== true'。这就是为什么我在谓词函数中使用'.last()'的原因。由于这种狡猾,我希望能够建立一个简单的方法来订阅正在触发的最后一个渲染事件,以便我可以在多个地方重复使用它。 –
您可以设置一个Observable,它每隔一段时间轮询一次地图,如果加载是真的,然后发射,则进行过滤。将尽快用代码更新答案。 –
谢谢,我想看看。 –