Leaflet健身应用:表单提交后训练项及天气数据异常排查
问题1:训练项提交显示异常的修复
核心原因
- 事件绑定逻辑错位:每次调用
_renderWorkout都会给地图绑定新的dblclick事件,但训练项创建本应在表单提交后完成,而非等待后续地图双击。首次提交时updateHTML从未执行,因此无内容;后续提交时,之前绑定的dblclick事件触发,导致渲染的是上一次的训练数据。 - DOM渲染时机滞后:原逻辑把HTML渲染放在双击事件内部,依赖异步的天气请求+双击触发,导致训练项无法在提交时即时生成。
修复方案
1. 重构数据流向与事件逻辑
将地图双击作为训练项创建的入口(而非在渲染方法内绑定),表单提交后直接使用选中的坐标获取天气并渲染。
2. 修改_renderWorkout方法
_renderWorkout(workout, latlng) { // 新增latlng参数,从创建入口传入 const updateHTML = (weatherTemp) => { let html = ` <li class="workout workout--${workout.type}" data-id="${workout.id}"> <h2 class="workout__title">${workout.description}</h2> <div class="workout__details"> <button class="delete__workout">Delete this workout</button> <button class="edit__workout">Edit your workout</button> <span class="workout__icon">${workout.type === 'running' ? '🏃♂️' : '🚴♀️'}</span> <span class="workout__value">${workout.distance}</span> <span class="workout__weather">${weatherTemp}F</span> <span class="workout__unit">km</span> </div> <div class="workout__details"> <span class="workout__icon">⏱</span> <span class="workout__value">${workout.duration}</span> <span class="workout__unit">min</span> </div> `; if (workout.type === 'running') { html += ` <div class="workout__details"> <span class="workout__icon">⚡️</span> <span class="workout__value">${workout.pace.toFixed(1)}</span> <span class="workout__unit">km/min</span> </div> <div class="workout__details"> <span class="workout__icon">🦶🏼</span> <span class="workout__value">${workout.cadence}</span> <span class="workout__unit">spm</span> </div> </li> `; } if (workout.type === 'cycling') { html += ` <div class="workout__details"> <span class="workout__icon">⚡️</span> <span class="workout__value">${workout.speed.toFixed(1)}</span> <span class="workout__unit">km/h</span> </div> <div class="workout__details"> <span class="workout__icon">⛰</span> <span class="workout__value">${workout.elevation}</span> <span class="workout__unit">m</span> </div> </li> `; } form.insertAdjacentHTML('afterend', html); this._setLocalStorage(); }; // 直接用当前坐标请求天气,无需等待双击 this._getFetchLocation(latlng.lat, latlng.lng) .then(temp => updateHTML(temp)) .catch(error => { console.error(error); updateHTML('N/A'); // 请求失败时显示替代文本 }); }
3. 调整训练项创建入口
// 将地图双击设为训练项创建的触发点 this.#map.on('dblclick', async ev => { const latlng = ev.latlng; // 从表单获取数据生成workout对象(自行实现_createWorkoutFromForm方法) const workout = this._createWorkoutFromForm(); this._renderWorkout(workout, latlng); });
问题2:天气数据显示默认值的排查与修复
可能原因
- API请求异常:天气API超时、返回错误,导致代码使用预设的34.6F默认值。
- 坐标传递错误:传入API的经纬度格式或数值不正确,触发API返回默认位置的天气。
- 异常处理缺失:
_getFetchLocation抛出错误时未正确处理,变量保留旧的默认值。
排查修复步骤
- 添加API请求日志:在
_getFetchLocation中打印请求参数和返回数据,确认问题点async _getFetchLocation(lat, lng) { console.log(`请求天气:lat=${lat}, lng=${lng}`); const res = await fetch(`你的天气API地址?lat=${lat}&lon=${lng}`); const data = await res.json(); console.log('API返回:', data); if (!res.ok) throw new Error('天气请求失败'); return data.main.temp; // 根据实际API返回结构调整 } - 完善异常处理:确保请求失败时不会沿用旧值,而是显示明确提示
- 验证坐标准确性:确认传递给
_getFetchLocation的经纬度是当前训练项对应的真实坐标,而非固定值或错误数据
内容的提问来源于stack exchange,提问作者Jules Mundur
相关产品推荐
相关产品推荐

