Map Context & Lifecycle
The MapContext is the central interface for interacting with your map at runtime. While MapSchema defines how the map should behave, the MapContext provides the tools to command it—allowing you to update data, zoom to features, and listen to user interactions.
This guide walks you through accessing the map context, grabbing layer APIs, and managing the feature lifecycle.
1. Listening for the "Ready" Event
The lifecycle of an AurOpenlayers map begins when the <mff-map-host> component finishes initializing the OpenLayers instance and processing your schema. At this point, it emits a ready event containing the MapContext.
First, bind to the event in your component template:
<mff-map-host
[config]="mapConfig"
(ready)="onReady($event)">
</mff-map-host>
Then, capture the context in your TypeScript class:
import { MapContext, VectorLayerApi } from 'aur-openlayers';
// ...
export class MyMapComponent {
private mapContext?: MapContext;
onReady(ctx: MapContext): void {
this.mapContext = ctx;
console.log('Map is ready!', ctx);
// You can now access layers and the raw OL map instance
// const olMap = ctx.map;
}
}
2. Accessing Layer APIs
Each layer defined in your MapSchema is exposed via a VectorLayerApi within the context. You access them using the unique id you provided in the layer descriptor.
It is a common practice to store these APIs as class properties for easy access:
private pointLayerApi?: VectorLayerApi<MyModel, Geometry>;
onReady(ctx: MapContext): void {
// Access the layer by the ID defined in your schema
this.pointLayerApi = ctx.layers['points-layer-id'];
// Initialize the layer with data
this.pointLayerApi.setModels(this.initialData);
}
3. Managing Feature Data (Models)
The VectorLayerApi is your primary tool for data synchronization. Instead of creating OpenLayers Feature objects manually, you pass your business models directly to the API.
Seeding Data
Use setModels() to replace the entire collection or addModels() to append new items.
this.pointLayerApi?.setModels([
{ id: '1', lat: 53.9, lng: 27.5, name: 'Minsk' },
{ id: '2', lat: 48.8, lng: 2.3, name: 'Paris' }
]);
// Optionally center the view on the new data
this.pointLayerApi?.centerOnAllModels();
Handling External Updates
If your business logic changes a model (e.g., via a side panel), calling setModels again with the updated objects will cause the framework to efficiently re-render only the affected features.
4. Subscribing to Map-Driven Changes
One of the framework's core strengths is two-way synchronization. When a user drags a point or modifies a polygon, the map communicates these changes back to your component.
Monitoring Model Changes
Use onModelsChanged to catch interactions like translate (dragging) or modify.
onReady(ctx: MapContext): void {
const layerApi = ctx.layers['points'];
layerApi.onModelsChanged?.((changes) => {
changes.forEach(({ prev, next, reason }) => {
console.log(`Model ${next.id} changed due to ${reason}`);
// Update your local component state or send to a backend API
this.updateMyDatabase(next);
});
});
}
Dealing with Angular's Change Detection
Since interactions happen inside the OpenLayers render loop (outside of Angular's NgZone), you must wrap state updates in zone.run() if you want the UI to reflect changes immediately.
constructor(private zone: NgZone) {}
// ... inside onModelsChanged
this.zone.run(() => {
this.selectedModel = next;
});
5. Cleaning Up
To prevent memory leaks, especially when dealing with subscriptions or global event listeners provided by the API, ensure you unsubscribe when the component is destroyed.
Many API methods return an Unsubscribe function:
private destroyCallback?: () => void;
onReady(ctx: MapContext): void {
const api = ctx.layers['points'];
this.destroyCallback = api.onModelsChanged?.((changes) => { /* ... */ });
}
ngOnDestroy(): void {
this.destroyCallback?.();
}
Summary Checklist
- Define IDs: Ensure your layers have clear, unique string IDs in the
MapSchema. - Handle
ready: Use the event to grab theMapContext. - Inject Data: Use
setModels()to populate the map. - Listen: Subscribe to
onModelsChangedfor user interactions. - Zone Awareness: Wrap UI updates in
NgZone.run().