javascript - Hur man har en händelsehanterare för någon callback (Leaflet-biblioteket) med Angular 8
Jag satt ihop en Angular 8-app som använder Leaflet-biblioteket. Jag slutade med lite fungerande kod men känner att det kanske inte är det bästa sättet att uppnå det jag ville. Läs gärna till slutet först...
Min komponent typescript-fil ser ut så här:
import { Component, OnInit } from '@angular/core';
declare let L;
@Component({
selector: 'app-new-hotspot-form',
templateUrl: './new-hotspot-form.component.html',
styleUrls: ['./new-hotspot-form.component.css']
})
export class NewHotspotFormComponent implements OnInit {
latitude: string = "51.505";
longitude: string = "-0.09";
name: string = "Hotspot 1";
radius: string = "5.0";
map: any;
constructor() { }
getOnMapClickHandler() {
const myComponent = this;
let clickHandler = function(e) {
myComponent.latitude = e.latlng.lat;
myComponent.longitude = e.latlng.lng;
myComponent.map.setView([e.latlng.lat, e.latlng.lng]);
};
return clickHandler;
}
ngOnInit() {
this.map = L.map('newhotspot').setView([this.latitude, this.longitude], 13);
this.map.on('click', this.getOnMapClickHandler());
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: '_MY_SECRET_ACCESS_TOKEN_'
}).addTo(this.map);
}
}
Och den motsvarande html-filen ser ut så här:
<div class="ui-fluid">
<div class="ui-g">
<div class="ui-g-12 ui-md-6">
<div class="ui-g-4">
Name
</div>
<div class="ui-g-8">
<input [(ngModel)]="name" pInputText type="text" />
</div>
</div>
<div class="ui-g-12 ui-md-6">
<div class="ui-g-4">
Radius
</div>
<div class="ui-g-8">
<input [(ngModel)]="radius" pInputText type="text" />
</div>
</div>
<div class="ui-g-12">
<div class="ui-g-2">
Location
</div>
<div class="ui-g-10">
<div id="newhotspot"></div>
</div>
</div>
<div class="ui-g-12 ui-md-6">
<div class="ui-g-4">
Longitude
</div>
<div class="ui-g-8">
<input [(ngModel)]="longitude" type="text" />
</div>
</div>
<div class="ui-g-12 ui-md-6">
<div class="ui-g-4">
Latitude
</div>
<div class="ui-g-8">
<input [(ngModel)]="latitude" pInputText type="text" />
</div>
</div>
</div>
</div>
primeng är också "i båten" men spelar ingen roll för denna fråga (hoppas jag...).
Jag tilldelade en händelsehanterare till mitt kartklikk och undrade varför datainbindningen jag gjorde inte fungerade. Tills jag upptäckte att min händelsehanterare inte har this tilldelat till min komponent. Jag ändrade då min kod till att göra en fabriksmetod som binder this på något sätt. Även om koden fungerar nu har jag en konstig magkänsla om det och undrade om det finns ett mer naturligt sätt att uppnå att händelsehanteraren fungerar korrekt.
Svar #1
Som AJT82 föreslog, borde fat arrow-funktionsyntax ge dig det du letar efter, t.ex. ändring
this.map.on('click', this.getOnMapClickHandler());Till
this.map.on('click', (e) => {
this.latitude = e.latlng.lat;
this.longitude = e.latlng.lng;
this.map.setView([e.latlng.lat, e.latlng.lng]);
}
Då kommer du att kunna ta bort getOnMapClickHandler.
