我正在創建需要通過按鈕和滑塊支持大量交互性的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,它每隔一段時間輪詢一次地圖,如果加載是真的,然後發射,則進行過濾。將盡快用代碼更新答案。 –
謝謝,我想看看。 –