I am just grasping Angular (6) framework, and it's quirks and features. And there is this one thing, that I would need, but as it seems, it goes against Angular paradigms - a service, that needs a reference to DOM node.
More specifically - Esri Map component. In it's constructor, it requires a DOM node - a place where the map will live. Since the Map is going to be the center thing in the application, it would be used by multiple components throughout the app. And for that, I would want it in a service. Question is - how would I do that? I made solution to this, but I would like to validate it with more experienced Angular devs.
So I have a MapComponent
that would be like a singleton component - included only once in the App.
export class MapComponent implements OnInit {
@ViewChild('map') mapElement:ElementRef;
constructor(
private renderer2: Renderer2,
private mapService: MapService) { }
ngOnInit() {
// This is where I pass my DOM element to the service, to initialize it
this.mapService.init(this.mapElement.nativeElement);
}
}
And my mapService, that I would reference throughout other services
@Injectable()
export class MapService {
private isInit:boolean = false;
private map: __esri.Map = null;
private mapView: __esri.MapView = null;
init(domElement: ElementRef) {
if (this.isInit) return Promise.resolve(); // A guard?
loadModules(["esri/Map", "esri/views/MapView", "esri/widgets/ScaleBar"])
.then(([Map, MapView, ScaleBar]) => {
this.map = new Map();
this.mapView = new MapView({
map: this.map,
container: domElement // This is where I need DOM element
});
})
.catch(err => {
// handle any errors
console.error(err);
})
.then(() => {
this.isInit = true;
});
}
}
This does work, I just wonder, would this be a correct way to do it. I require these map objects to be accessible through other components, to add/remove/change map layers, draw/render geometries and other map things.