Leaflet JS:在承诺中定义更新功能;教程的变化
Leaflet JS: defining update function within promise; variation on tutorial
本教程的变体:https://leafletjs.com/examples/choropleth/。我正在尝试添加自定义信息控件。
let info = L.control();
function highlightFeature(e) {
...
info.update(layer.feature.properties);
}
function resetHighlight(e) {
...
info.update();
}
function updateFunction(tab, props) {
this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ?
'<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
: 'Hover over a state');
}
info.onAdd = function(map) {
this._div = L.DomUtil.create("div", "info");
this.update();
return this._div;
}
let statedata = fetch(url + stateurl).then(data => data.json());
statedata.then((data) => {
info.update = (props) => updateFunction(data, props);
let style = (feature) => styleMap(data, feature);
info.addTo(mymap);
geojson = L.geoJson(statesData, {style : style, onEachFeature: onEachFeature}).addTo(mymap);
});
在这里,我的info.update
与教程略有不同。 info.update
和 style
取决于我只能在底部的异步部分中访问的 json 数据。但是,此代码给我以下错误:Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of undefined
,指的是 updateFunction 的 this._div
行。
我发现如果我执行以下任一操作
- 移动
let info = L.control()
和我所有依赖于 info
的函数或
- 在 promise 之外定义
info.update
,
那么代码将正常运行。然而,选项 1 看起来很可怕并且在道德上是不正确的,选项 2 使我不得不放弃访问状态数据的希望 json。另外,在选项 2 中,我不明白在承诺内部或外部声明 info.update
有什么区别。特别是,为什么在 promise 内声明 info.update 会导致 info._div
的未定义行为,而在 promise 外声明 info.update
则不会?
如能提供任何关于此处错误的线索,我们将不胜感激!
在您使用的教程中,这是他们为 info.update
:
info.update = function (props) {
this._div.innerHTML = '<h4>US Population Density</h4>' + (props ?
'<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
: 'Hover over a state');
};
在此函数中,this
将引用 info
对象。在您的代码中,您重构为:
function updateFunction(tab, props) {
this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ?
'<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
: 'Hover over a state');
}
// ...
info.update = (props) => updateFunction(data, props);
通过使用调用常规函数的箭头函数,您有效地切断了 info
和 this
之间的联系。在您的情况下,this
可能默认为 window
,这可以解释为什么 _div
未定义。
要解决此问题,您需要明确地 bind this
到 info
。你可以这样做:
info.update = (props) => updateFunction.bind(info)(data, props);
或者更简洁,您可以简单地绑定 this
和第一个参数,并完全跳过中间的箭头函数:
info.update = updateFunction.bind(info, data);
本教程的变体:https://leafletjs.com/examples/choropleth/。我正在尝试添加自定义信息控件。
let info = L.control();
function highlightFeature(e) {
...
info.update(layer.feature.properties);
}
function resetHighlight(e) {
...
info.update();
}
function updateFunction(tab, props) {
this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ?
'<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
: 'Hover over a state');
}
info.onAdd = function(map) {
this._div = L.DomUtil.create("div", "info");
this.update();
return this._div;
}
let statedata = fetch(url + stateurl).then(data => data.json());
statedata.then((data) => {
info.update = (props) => updateFunction(data, props);
let style = (feature) => styleMap(data, feature);
info.addTo(mymap);
geojson = L.geoJson(statesData, {style : style, onEachFeature: onEachFeature}).addTo(mymap);
});
在这里,我的info.update
与教程略有不同。 info.update
和 style
取决于我只能在底部的异步部分中访问的 json 数据。但是,此代码给我以下错误:Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of undefined
,指的是 updateFunction 的 this._div
行。
我发现如果我执行以下任一操作
- 移动
let info = L.control()
和我所有依赖于info
的函数或 - 在 promise 之外定义
info.update
,
那么代码将正常运行。然而,选项 1 看起来很可怕并且在道德上是不正确的,选项 2 使我不得不放弃访问状态数据的希望 json。另外,在选项 2 中,我不明白在承诺内部或外部声明 info.update
有什么区别。特别是,为什么在 promise 内声明 info.update 会导致 info._div
的未定义行为,而在 promise 外声明 info.update
则不会?
如能提供任何关于此处错误的线索,我们将不胜感激!
在您使用的教程中,这是他们为 info.update
:
info.update = function (props) {
this._div.innerHTML = '<h4>US Population Density</h4>' + (props ?
'<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
: 'Hover over a state');
};
在此函数中,this
将引用 info
对象。在您的代码中,您重构为:
function updateFunction(tab, props) {
this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' + (props ?
'<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
: 'Hover over a state');
}
// ...
info.update = (props) => updateFunction(data, props);
通过使用调用常规函数的箭头函数,您有效地切断了 info
和 this
之间的联系。在您的情况下,this
可能默认为 window
,这可以解释为什么 _div
未定义。
要解决此问题,您需要明确地 bind this
到 info
。你可以这样做:
info.update = (props) => updateFunction.bind(info)(data, props);
或者更简洁,您可以简单地绑定 this
和第一个参数,并完全跳过中间的箭头函数:
info.update = updateFunction.bind(info, data);