Leaflet JS Promise内定义info.update触发this._div未定义问题咨询
问题根因
你遇到的报错本质是updateFunction运行时的this指向丢失,具体由以下错误写法导致:
你在Promise回调中给info.update赋值的是箭头函数,内部调用updateFunction时采用普通函数调用规则,没有显式绑定执行上下文。此时updateFunction内部的this在非严格模式下指向全局window对象,严格模式下为undefined,自然找不到绑定在info实例上的_div属性,触发Cannot set property 'innerHTML' of undefined报错。
可行解决方法
以下方案均不需要把全部控件逻辑移入Promise,也不会出现数据无法访问的问题:
方案1:修复this指向绑定
把info.update的赋值改为普通函数,将this透传给updateFunction:
statedata.then((data) => { // 不用箭头函数,普通函数作为info方法调用时this自动指向info实例 info.update = function(props) { return updateFunction.call(this, data, props); }; // 其余逻辑保持不变 let style = (feature) => styleMap(data, feature); info.addTo(mymap); geojson = L.geoJson(statesData, {style : style, onEachFeature: onEachFeature}).addTo(mymap); });
方案2:上层作用域缓存异步数据,提前定义update方法
在全局/上层作用域声明变量存储异步加载的state数据,提前在外部完成info.update的定义,数据和控件逻辑完全解耦:
// 上层作用域声明缓存变量 let stateDataCache = null; let info = L.control(); // 提前定义update方法 info.update = function(props) { // 数据未加载完成时跳过渲染 if (!stateDataCache) return; this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ? '<b>' + props.name + '</b><br />' + getActive(stateDataCache, props.name) + ' cases' : 'Hover over a state'); }; // highlightFeature、resetHighlight、info.onAdd等原有逻辑保持不变 statedata.then((data) => { // 仅给缓存变量赋值即可 stateDataCache = data; let style = (feature) => styleMap(data, feature); info.addTo(mymap); geojson = L.geoJson(statesData, {style : style, onEachFeature: onEachFeature}).addTo(mymap); });
方案3:直接规避this指向问题
如果不想处理this绑定逻辑,可以直接在updateFunction中通过上层作用域的info变量访问_div属性,无需依赖this:
const info = L.control(); function updateFunction(tab, props) { // 直接用info变量访问实例属性,不需要this info._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ? '<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases' : 'Hover over a state'); }
这个改法代码改动最小,也不会出现上下文丢失的问题。
内容的提问来源于stack exchange,提问作者Ethan Martin
相关产品推荐
相关产品推荐

