Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable zoneless app #191

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"outputPath": "dist/showcase",
"index": "projects/showcase/src/index.html",
"browser": "projects/showcase/src/main.ts",
"polyfills": ["zone.js"],
"tsConfig": "projects/showcase/tsconfig.app.json",
"assets": [
"projects/showcase/src/favicon.ico",
Expand Down
8 changes: 1 addition & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"maplibre-gl": "^4.6.0",
"rxjs": "7.8.1",
"scroll-into-view-if-needed": "^3.1.0",
"tslib": "^2.6.3",
"zone.js": "~0.14.4"
"tslib": "^2.6.3"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.2.1",
Expand Down
6 changes: 2 additions & 4 deletions projects/ngx-maplibre-gl/src/lib/map/map.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,8 @@ export class MapComponent implements OnChanges, OnDestroy, MapEvent {
viewChild.required<ElementRef<HTMLDivElement>>('container');

constructor() {
afterRender(() => this.mapService.clearMapElements());
n-elhk marked this conversation as resolved.
Show resolved Hide resolved

afterNextRender(() => {
if (this.preserveDrawingBuffer()) {
// This is to allow better interaction with the map state
Expand Down Expand Up @@ -341,10 +343,6 @@ export class MapComponent implements OnChanges, OnDestroy, MapEvent {
this.mapService.changeCanvasCursor(cursorStyle);
}
});

afterRender(() => {
this.mapService.clearMapElements();
});
}

ngOnDestroy() {
Expand Down
1 change: 1 addition & 0 deletions projects/ngx-maplibre-gl/src/lib/map/map.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ export class MapService {

const isIEorEdge =
window && /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);

if (isIEorEdge) {
this.mapInstance.setStyle(options.style!);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,27 @@ import {
inject,
input,
signal,
} from '@angular/core';
} from "@angular/core";
import type {
MapGeoJSONFeature,
MapSourceDataEvent,
QueryRenderedFeaturesOptions,
} from 'maplibre-gl';
import { fromEvent, merge } from 'rxjs';
import { filter, startWith, switchMap } from 'rxjs/operators';
import { MapService } from '../map/map.service';
import { MarkerComponent } from '../marker/marker.component';
import { NgTemplateOutlet } from '@angular/common';
import { LayerComponent } from '../layer/layer.component';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
} from "maplibre-gl";
import { fromEvent, merge } from "rxjs";
import { filter, startWith, switchMap } from "rxjs/operators";
import { MapService } from "../map/map.service";
import { MarkerComponent } from "../marker/marker.component";
import { NgTemplateOutlet } from "@angular/common";
import { LayerComponent } from "../layer/layer.component";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";

/**
* a template directive for point for {@link MarkersForClustersComponent}
*
* @category Directives
*/
@Directive({
selector: 'ng-template[mglPoint]',
selector: "ng-template[mglPoint]",
standalone: true,
})
export class PointDirective {}
Expand All @@ -41,7 +41,7 @@ export class PointDirective {}
* @category Directives
*/
@Directive({
selector: 'ng-template[mglClusterPoint]',
selector: "ng-template[mglClusterPoint]",
standalone: true,
})
export class ClusterPointDirective {}
Expand Down Expand Up @@ -71,30 +71,29 @@ let uniqId = 0;
* Note: Only use this if you **really** need to use HTML/Angular component to render your symbols. This is **slower** than rendering symbols in WebGL.
*/
@Component({
selector: 'mgl-markers-for-clusters',
selector: "mgl-markers-for-clusters",

template: `
<mgl-layer
template: ` <mgl-layer
[id]="layerId"
[source]="source()"
type="circle"
[paint]="{ 'circle-radius': 0 }"
></mgl-layer>
@for (feature of clusterPoints(); track $index) {
@if (feature.properties.cluster) {
<mgl-marker [feature]="feature">
<ng-container
*ngTemplateOutlet="clusterPointTpl(); context: { $implicit: feature }"
></ng-container>
</mgl-marker>
} @else {
<mgl-marker [feature]="feature">
<ng-container
*ngTemplateOutlet="pointTpl(); context: { $implicit: feature }"
></ng-container>
</mgl-marker>
}
}`,
<mgl-marker [feature]="feature">
<ng-container
*ngTemplateOutlet="clusterPointTpl(); context: { $implicit: feature }"
></ng-container>
</mgl-marker>
} @else {
<mgl-marker [feature]="feature">
<ng-container
*ngTemplateOutlet="pointTpl(); context: { $implicit: feature }"
></ng-container>
</mgl-marker>
}
}`,
changeDetection: ChangeDetectionStrategy.OnPush,
preserveWhitespaces: false,
standalone: true,
Expand Down Expand Up @@ -131,11 +130,11 @@ export class MarkersForClustersComponent {
constructor() {
afterNextRender(() => {
const clusterDataUpdate = () =>
fromEvent<MapSourceDataEvent>(this.mapService.mapInstance, 'data').pipe(
fromEvent<MapSourceDataEvent>(this.mapService.mapInstance, "data").pipe(
filter(
(e) =>
e.sourceId === this.source() &&
e.sourceDataType !== 'metadata' &&
e.sourceDataType !== "metadata" &&
this.mapService.mapInstance.isSourceLoaded(this.source())
)
);
Expand All @@ -144,8 +143,8 @@ export class MarkersForClustersComponent {
switchMap(clusterDataUpdate),
switchMap(() =>
merge(
fromEvent(this.mapService.mapInstance, 'move'),
fromEvent(this.mapService.mapInstance, 'moveend')
fromEvent(this.mapService.mapInstance, "move"),
fromEvent(this.mapService.mapInstance, "moveend")
).pipe(startWith(undefined))
)
)
Expand All @@ -169,7 +168,7 @@ export class MarkersForClustersComponent {
pointTpl: TemplateRef<PointDirective> | undefined
): QueryRenderedFeaturesOptions {
if (!pointTpl) {
return { layers: [this.layerId], filter: ['==', 'cluster', true] };
return { layers: [this.layerId], filter: ["==", "cluster", true] };
}

return { layers: [this.layerId] };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import {
inject,
input,
signal,
} from '@angular/core';
import type { GeoJSONSource, GeoJSONSourceSpecification } from 'maplibre-gl';
import { Subject } from 'rxjs';
import { debounceTime, switchMap, tap } from 'rxjs/operators';
import { SourceDirective } from '../source.directive';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
} from "@angular/core";
import type { GeoJSONSource, GeoJSONSourceSpecification } from "maplibre-gl";
import { Subject } from "rxjs";
import { debounceTime, switchMap, tap } from "rxjs/operators";
import { SourceDirective } from "../source.directive";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";

/**
* `mgl-geojson-source` - a geojson source component
Expand Down Expand Up @@ -43,10 +43,10 @@ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
* ```
*/
@Component({
selector: 'mgl-geojson-source',
template: '',
selector: "mgl-geojson-source",
template: "",
changeDetection: ChangeDetectionStrategy.OnPush,
hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
hostDirectives: [{ directive: SourceDirective, inputs: ["id"] }],
standalone: true,
})
export class GeoJSONSourceComponent implements OnChanges {
Expand All @@ -57,52 +57,52 @@ export class GeoJSONSourceComponent implements OnChanges {
private readonly ngZone = inject(NgZone);

/** Dynamic input */
readonly data = input<GeoJSONSourceSpecification['data']>({
type: 'FeatureCollection',
readonly data = input<GeoJSONSourceSpecification["data"]>({
type: "FeatureCollection",
features: [],
});

/** Dynamic input */
readonly maxzoom = input<GeoJSONSourceSpecification['maxzoom']>();
readonly maxzoom = input<GeoJSONSourceSpecification["maxzoom"]>();

/** Dynamic input */
readonly attribution = input<GeoJSONSourceSpecification['attribution']>();
readonly attribution = input<GeoJSONSourceSpecification["attribution"]>();

/** Dynamic input */
readonly buffer = input<GeoJSONSourceSpecification['buffer']>();
readonly buffer = input<GeoJSONSourceSpecification["buffer"]>();

/** Dynamic input */
readonly tolerance = input<GeoJSONSourceSpecification['tolerance']>();
readonly tolerance = input<GeoJSONSourceSpecification["tolerance"]>();

/** Dynamic input */
readonly cluster = input<GeoJSONSourceSpecification['cluster']>();
readonly cluster = input<GeoJSONSourceSpecification["cluster"]>();

/** Dynamic input */
readonly clusterRadius = input<GeoJSONSourceSpecification['clusterRadius']>();
readonly clusterRadius = input<GeoJSONSourceSpecification["clusterRadius"]>();

/** Dynamic input */
readonly clusterMaxZoom =
input<GeoJSONSourceSpecification['clusterMaxZoom']>();
input<GeoJSONSourceSpecification["clusterMaxZoom"]>();

/** Dynamic input */
readonly clusterMinPoints =
input<GeoJSONSourceSpecification['clusterMinPoints']>();
input<GeoJSONSourceSpecification["clusterMinPoints"]>();

/** Dynamic input */
readonly clusterProperties =
input<GeoJSONSourceSpecification['clusterProperties']>();
input<GeoJSONSourceSpecification["clusterProperties"]>();

/** Dynamic input */
readonly lineMetrics = input<GeoJSONSourceSpecification['lineMetrics']>();
readonly lineMetrics = input<GeoJSONSourceSpecification["lineMetrics"]>();

/** Dynamic input */
readonly generateId = input<GeoJSONSourceSpecification['generateId']>();
readonly generateId = input<GeoJSONSourceSpecification["generateId"]>();

/** Dynamic input */
readonly promoteId = input<GeoJSONSourceSpecification['promoteId']>();
readonly promoteId = input<GeoJSONSourceSpecification["promoteId"]>();

/** Dynamic input */
readonly filter = input<GeoJSONSourceSpecification['filter']>();
readonly filter = input<GeoJSONSourceSpecification["filter"]>();

private readonly updateFeatureDataSubject = new Subject<void>();

Expand Down Expand Up @@ -216,7 +216,7 @@ export class GeoJSONSourceComponent implements OnChanges {

private getGeoJSONSourceSpecification(): GeoJSONSourceSpecification {
return {
type: 'geojson',
type: "geojson",
data: this.data(),
maxzoom: this.maxzoom(),
attribution: this.attribution(),
Expand Down
2 changes: 0 additions & 2 deletions projects/ngx-maplibre-gl/src/test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files

import 'zone.js';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
Expand Down
19 changes: 10 additions & 9 deletions projects/showcase/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
import { Component, inject } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from '@angular/platform-browser';
import { RouterOutlet } from '@angular/router';
import { ChangeDetectionStrategy, Component, inject } from "@angular/core";
import { MatIconRegistry } from "@angular/material/icon";
import { DomSanitizer } from "@angular/platform-browser";
import { RouterOutlet } from "@angular/router";

import github from '../assets/github.svg';
import logo from '../assets/ngx-maplibre-gl.svg';
import github from "../assets/github.svg";
import logo from "../assets/ngx-maplibre-gl.svg";

@Component({
selector: 'showcase-root',
selector: "showcase-root",
template: `<router-outlet></router-outlet>`,
standalone: true,
imports: [RouterOutlet],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
private readonly iconRegistry = inject(MatIconRegistry);
private readonly sanitizer = inject(DomSanitizer);

constructor() {
this.iconRegistry.addSvgIconLiteral(
'ngx-maplibre-gl',
"ngx-maplibre-gl",
this.sanitizer.bypassSecurityTrustHtml(logo)
);
this.iconRegistry.addSvgIconLiteral(
'github',
"github",
this.sanitizer.bypassSecurityTrustHtml(github)
);
}
Expand Down
6 changes: 2 additions & 4 deletions projects/showcase/src/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { ApplicationConfig, provideExperimentalZonelessChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideClientHydration } from '@angular/platform-browser';

export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideExperimentalZonelessChangeDetection(),
provideRouter(routes),
provideHttpClient(withFetch()),
provideAnimations(),
provideClientHydration(),
],
};
Loading
Loading