我正在使用 Leaflet Draw 将一些图钉移动到新位置并将这些位置保存到数据库中。
我还有一个包含 2 个字段的表单,使用户可以通过直接在名称和纬度/经度字段中输入详细信息来更改图钉的名称和纬度/经度。
为此,他们首先单击一个图钉,该图钉使用当前详细信息填充字段,用户可以更改这些信息,然后更新图钉详细信息。
一切正常,除了一个怪癖,这意味着您必须在 pin 上单击两次才能使用 pin 详细信息更新表单字段。事实上,我发现不一定要点击图钉两次,而是点击地图上的任何交互式元素都会使更新发生,例如另一个图钉、锚链接或任何表单字段。
我已经尝试了很多想法,试图让表单字段只需单击 1 次即可更新,但无法弄清楚为什么会发生这种情况。
任何关于为什么需要单击两次或如何解决问题以便只需要单击一次的任何想法都将非常受欢迎。
我正在使用 Angular、Leaflet 和 Leaflet Draw。用于显示地图和表单字段的地图编辑器组件、用于实现 Leaflet Draw 功能的地图绘制服务以及用于放置图钉和执行更新的地图编辑器服务。
为简洁起见,我只会在下面包含我认为的相关代码片段,但如果您需要任何其他代码片段,请询问。
我还附上了一个在编辑模式下引脚和字段的截图。
顺便说一句,表单字段使用 ngModel 绑定到活动标记,因此这些值会自动更新标记数据,以便以后保存。不过,我不确定这是否是最好的方法。
on mouseup 函数中的 console.log 消息显示标记对象在第一次单击时正确更新,只是数据在第二次单击之前没有进入表单字段。
地图编辑器.component.ts
...
updateLatLng(marker, latlng) {
this.mapEditorService.updateLatLng(marker, Math.fround(latlng.split(',')[0]).toPrecision(6), Math.fround(latlng.split(',')[1]).toPrecision(6));
}
...
地图编辑器.component.html
<div class="editor" *ngIf="auth.isAuthenicated(true)" [ngClass]="{'profile': profile}">
<div class="map"
leaflet
(leafletMapReady)="onMapReady($event); mapDrawService.onMapReady()"
[leafletOptions]="mapEditorService.options"
leafletDraw
(leafletDrawReady)="mapDrawService.initialise($event)"
(leafletDrawCreated)="mapDrawService.onDrawCreated($event)"
(leafletDrawStart)="mapDrawService.onDrawEdit($event)"
(leafletDrawEdited)="mapDrawService.saveEdits($event)"
(leafletDrawEditStart)="mapDrawService.editStart($event)"
(leafletDrawEditStop)="mapDrawService.editStop($event)"
(leafletDrawEditMove)="mapDrawService.onDrawMove($event)"
(leafletDrawDeleted)="mapDrawService.onDrawDelete($event)"
[leafletDrawOptions]="mapDrawService.options"
>
</div>
<div *ngIf="mapEditorService.inEditMode" id="latlng-wrapper" class="latlng-wrapper">
<div><input [(ngModel)]="mapEditorService.selectedMarker._data.dest" type="text" id="latlngLabel" class="latlngLabel" placeholder="Pin Title" /></div>
<div class="lnglng-row2">
<input (ngModelChange)="updateLatLng(mapEditorService.selectedMarker, $event)" [ngModel]="(mapEditorService.selectedMarker.getLatLng().lat | number:'1.6-6') + ',' + (mapEditorService.selectedMarker.getLatLng().lng | number:'1.6-6')" type="text" id="latlng" class="latlng" placeholder="Enter Lat,Lon" />
<input type="button" id="latlngBtn" value="Pan To Pin" class="btn btn-secondary latlngBtn" (click)="mapEditorService.panToCoords(mapEditorService.selectedMarker.getLatLng().lat, mapEditorService.selectedMarker.getLatLng().lng)" />
</div>
</div>
<div id="reset-wrapper" class="reset-wrapper">
<input type="button" id="resetBtn" value="Pan To Station" class="btn btn-secondary resetBtn" (click)="mapEditorService.panToCoords(mapEditorService.stn.profile.label_position.lat, mapEditorService.stn.profile.label_position.lng)" />
</div>
<button class="btn btn-small btn-success save-profile" (click)="mapDrawService.saveBounds()">Save profile</button>
</div>
地图绘制.service.ts
onDrawCreated(e: any) {
this.activeLayer.addLayer((e as DrawEvents.Created).layer);
this.activeLayer._layers[e.layer._leaflet_id]._data = this.lastMarkerAdded._data;
this.activeLayer._layers[e.layer._leaflet_id]._edited = true;
}
onDrawEdit(e: any) {
// console.log('in onDrawEdit');
}
onDrawDelete(e: any) {
this.delete(toArray(e.layers._layers).map(l => ({
_data: l._data
})));
}
onDrawMove(e) {
this.activeLayer._layers[e.layer._leaflet_id]._edited = true;
}
editStart(e) {
this.mapEditorService.inEditMode = true;
}
editStop(e) {
this.activeLayer.eachLayer(l => l._edited = false);
this.mapEditorService.inEditMode = false;
}
地图编辑器.service.ts
addMarker(layer, item, type) {
...
item.marker = L.marker(
[item.latitude, item.longitude],
{icon: L.icon(new CustomMarker('DS', 'bus',
{
fgColor: 'purple',
bgColor: 'white',
textColor: 'purple'
}, {
// custom marker code goes here
})
.create())})
.addTo(layer)
.on('mouseup', (e: any) => {
if (this.inEditMode) {
this.selectedMarker = item.marker;
console.log('event = ', e.type);
console.log('this.selectedMarker = ', this.selectedMarker);
} else {
return;
}
})
.bindTooltip(item.name, { direction: 'right', offset: [7, -13] });
item.marker._data = {
type: 'destination',
id: item.id,
label: 'DS',
crs: item.crs,
dest: item.name,
};
...
}
panToCoords(lat: number, lon: number) {
this.map.panTo([lat, lon], { animate: true });
}
updateLatLng(marker, lat, lng) {
marker.setLatLng(new L.LatLng(lat, lng));
}