Az Angular Leaflet térképek egyszerű útmutatója
A Leaflet az egyik legfontosabb Javascript-alapú térképezési keretrendszer. Az iparágban széles körben használják interaktív térképek hozzáadására weboldalakhoz és alkalmazásokhoz.
Az Angular.io alkalmazásokba való beépítése azonban trükkös lehet. Nem igazán játszik jól sem az Angularral, sem a Typescripttel. Miután átéltem azt a kalandot, hogy egy Leaflet térképalapú webhelyet Angular 8-ra migráltam, világossá vált számomra, hogy nincs igazán jó referencia ehhez a feladathoz. Ezek a bejegyzések a tanulságok dokumentálására tett kísérletem. (UPDATE: Bár ez a cikk Angular 8-ra íródott – az alkalmazások és módszerek Angular 11-ben is működnek).
Ez egy többrészes bejegyzés lesz :
- Az alapok (ez a bejegyzés),
- Vezérlők hozzáadása,
- Funkciók & Dinamikus vezérlők,
- Egyéni vezérlők, és
- Going PWA – service workers and more
A sorozat célja, hogy egy Angular-CLI alapú projektben gond, felhajtás és zsákutcák nélkül tudj létrehozni egy Leaflet leképezést.
Kiderült, hogy bár a Leaflet hozzáadása az Angular.io-hoz nem jelentősen nehéz, de nagyon “fiddlinges”, mivel a Leaflet nem kifejezetten Angular (vagy Typescript) barát. A Leaflet egy globális L
változóstruktúrát és .extend
módszereket használ, amelyek összezavarják a TS-t. Emellett olyan mennyiségű eseményt dolgoz fel, amelyek térdre kényszerítenék az Angular alkalmazásokat, ha változásérzékelésen mennének keresztül.
Szerencsére van egy jó kiindulópont a @asymmetrik/ngx-leaflet
-ban. Ez egy nagyjából boilerplate beállítást biztosít az alap leképezésekhez. jön egy pár jó tutorial is az alap leképezésekhez (itt és itt), de úgy tűnik, hogy elvesztették az érdeklődésüket, mielőtt a kemény dolgokhoz értek volna.
Getting Started
A dokumentáció szerint telepíteni kell :
npm install leaflet
npm install @types/leaflet
npm install @asymmetrik/ngx-leaflet
és hozzá kell adni az importokat a app.module.ts
-hoz.
Ezzel a ponttal – nagyjából egy egyszerű térképet tudsz hozzáadni az alkalmazáshoz, így azt gondolhatod, hogy mi volt ez a nagy felhajtás – de erre még rátérünk.
CSS komplikációk
Először is beszélnünk kell a CSS-ről. Az Ngx-leaflet a leafletet magán az Angularon kívül futtatja – ami tudomásom szerint a legjobb módja annak, hogy a Leaflet események ne okozzanak többszörös változtatási eseményeket az Angularban.
A Leaflet azonban, valószínűleg emiatt, nem illik bele az Angular.io CSS kapszulázási rendszerébe, és minden CSS hivatkozásnak globális szinten kell lennie.
Ez általában azt jelenti, hogy a Leaflet CSS-t az angular.json-ban adjuk hozzá a következőképpen
{
...
"styles": ,
...
}
vagy a styles.css-ben:
@import "./node_modules/leaflet/dist/leaflet.css"
Ez igaz az egyes vezérlők stíluslapjaira is, ami fárasztóvá válik, mivel a Leafletben minden vezérlőnek saját CSS-e van. Én azt találtam a legjobbnak, ha a Leaflet CSS-t a angular.json
-be, az egyes vezérlőelemek CSS-ét pedig a styles.css
-be adom, elsősorban a jobb olvashatóság miatt.
Megjegyzem, hogy mindkét esetben a leaflet.css-t a styles.css-ben lévő többi CSS előtt kell feldolgozni. Ellenkező esetben a vezérlőelemek CSS-e nem lesz hatékony.
Compiler komplikációk
Ez az a pont, ahol szintén elkezdünk találkozni az egyik első fordítói komplikációval.
Az így létrehozott leaflet alapú alkalmazások működnek ng build
esetén és működnek "aot": true
vel, de úgy tűnik, hogy az alapértelmezettng build --prod
konfigurációnál csúnyán megbuknak.
Ez úgy tűnik, hogy az optimalizáció körül van, és szerintem talán a fa rázásának köszönhető. Némi kísérletezés után rájöttem, hogy a ng build --prod
megbízhatóan működik, amíg a "buildOptimizer": false
a angular.json
-ben van.
Ne akadj fenn az L-ben
A legtöbb oktatóanyag és dokumentáció azt mondja, hogy a globális L
változót a következő import :
import * as L from 'leaflet'
segítségével kell behozni a typescriptbe :
import * as L from 'leaflet'
Ez igaz, ha meglévő JS kódot akarsz használni közvetlenül a TS-ben, de én úgy találtam, hogy amíg betöltötted a @types/leaflet
-ot, addig a tipedefeket név szerint importálhatod a 'leaflet'
-ből (e.Pl. import {Map} from 'leaflet'
és minden az elvárásoknak megfelelően működik. Ez sokkal olvashatóbbá és, nos, TS-esebbé teszi a TS kódodat!
A Simple Map
Szóval. Hozzuk létre a térképünket. Az alábbi példában egy OpenStreetMap térképet hozok létre (mivel az alkalmazásom ezen dolgozik) külön komponensként. Ezen a szinten ez extra munkának tűnhet, de később látni fogjuk, lehetővé teszi számunkra, hogy egy olyan térképkomponenst hozzunk létre további funkciókkal, amely az alkalmazás folyamában több helyen is újra felhasználható.
Ez a komponens alapértelmezetten egy OSM réteget és egy globális nézetet állít be az opciókban – bár az opciókat @Inputs()
ként állítjuk be, így az alapértelmezéseket a szülő komponens felülbírálhatja.
A térképkomponens eseményeket is kibocsát, amikor a térkép készen áll, hogy az alkalmazás más részei is hozzáférjenek a térképhez, valamint egy zoom esemény után az új nagyítási szintet. Más eseményeket is kibocsáthat, mint például a mozgatás és a réteg eseményeket – de az én alkalmazásomnak erre volt szüksége, és azt hiszem, ez mutatja az elvet. A térkép és a zoom eseményeket a következő szakaszokban fogjuk használni.
A térképet az ngx-leaflet direktíva segítségével adjuk hozzá a domhoz a komponens HTML-ben.
Végül a komponenst úgy használjuk, hogy a következőket adjuk hozzá a szülő HTML-hez:
<app-osm-map
="options"
(map$)="receiveMap($event)"
(zoom$)="receiveZoom($event)"
></app-osm-map>