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>

Read This Next