Closed AndreasSchmid1 closed 6 years ago
You can. It depends on the complexity of the control and what you're trying to do specifically. But, you could use the (leafletMapReady)
output binding to get a handle to the map and then you can do whatever you want to (add a custom control, add event handlers, etc.).
If you want to wrap it into a custom component or directive that works with ngx-leaflet, you can use https://github.com/Asymmetrik/ngx-leaflet-draw or https://github.com/Asymmetrik/ngx-leaflet-markercluster as examples of how to inject the LeafletDirective
into your custom component/directive. That allows you direct access to the map and other functionality within ngx-leaflet.
Check the ngx-leaflet README for details about making sure change detection works on changes in event handlers.
Thank you very much @reblace I will try that
I'm trying to write my first native typescript (without js dependencies) leaflet plugin and I am struggling a little bit. What I tried (I started with a service before trying a directive):
/*
* L.Control.ZoomDisplay shows the current map zoom level
*/
import { Injectable } from '@angular/core';
import * as L from 'leaflet';
@Injectable()
export class LeafletControlPower {
zoomDisplay = L.Control.extend({
options: {
position: 'topleft'
},
onAdd: function (map) {
this._map = map;
this._container = L.DomUtil.create('div', 'leaflet-control-zoom-display leaflet-bar-part leaflet-bar');
this.updateMapZoom(map.getZoom());
map.on('zoomend', this.onMapZoomEnd, this);
return this._container;
},
onRemove: function (map) {
map.off('zoomend', this.onMapZoomEnd, this);
},
onMapZoomEnd: function (e) {
this.updateMapZoom(this._map.getZoom());
},
updateMapZoom: function (zoom) {
if(typeof(zoom) === "undefined"){zoom = ""}
this._container.innerHTML = zoom;
}
});
mergeOptions = L.Map.mergeOptions({
zoomDisplayControl: true
});
addInitHook = L.Map.addInitHook(function () {
if (this.options.zoomDisplayControl) {
this.zoomDisplayControl = new this.zoomDisplay();
this.addControl(this.zoomDisplayControl);
}
});
constructor() {
}
public ZoomDisplay(options: any)
{
return new this.zoomDisplay(options);
}
}
this.powerControl.ZoomDisplay({}).addTo(this.map);
An error comes up: TypeError: this.zoomDisplay is not a constructor
I am pretty sure that I did a lot wrong here because i don't understand how to transform the js concept of this class into the directive/service concept of angular. I am also wondering if my the idea (writing native typescript plugins) makes sense. The idea came to me only because I can debug with VS code.
Thanks for this tutorial section @asymmetrik , it helped me a lot.
I integrated the following custom lib https://github.com/whitequark/Leaflet.Nanoscale
Things I did:
I added the Control.Nanoscale.js to assets/js/Control.Nanoscale.js
I added "import * as L from 'leaflet'" to Control.Nanoscale.js because otherwise you will receive an (error "ReferenceError: L is not defined")
I added "scripts": [ "../src/assets/js/Leaflet.Nanoscale.js" ],
Added typings
import * as L from 'leaflet'; declare module 'leaflet' { var nanoscale: any; }
Added the nanoscale control
import "../../../assets/js/Control.Nanoscale.js";
L.control.nanoscale({ nanometersPerPixel: 1000, }).addTo(this.map);
But the code of Control.Nanoscale.js is so short I would prefer to write the code in typescript myself.
Is it technically possible to write leaflet plugins in Angular / typescript?
Thank you for help in advance