Angular 中内容的 ArcGIS 4.16 弹出模板自定义函数
ArcGIS 4.16 popup template custom function for content in Angular
我正在尝试在服务返回结果的弹出模板中添加自定义内容。服务功能在 ngOninit() 或不属于弹出模板功能的自定义功能中工作。曾经在弹窗自定义模板功能中使用时,服务无法收集结果。
请找到下面的代码(只包含主要部分),导入自定义服务。
import { CustomService } from '../shared/service/custom.service';
constructor(private customService: CustomService){}
// Formation of the popup template
var popupTrailheads = {
title: "Unique id: {ID}",
content: this.getcustomcontent,
};
形成特征层弹出窗口应该来自这一层。
this.layer_fifteen = new FeatureLayer({
url: `${this.esriURL}/15`,
visible: true,
outFields: ['*'],
popupTemplate: popupTrailheads
});
下面的函数 getcustomcontent() 从服务中收集详细信息。
public getcustomcontent(feature) {
// the service code
this.customService.getIdDetails(popup_id).subscribe((posts) => {
//required to get the result from the service
}
}
当我使用 try-catch 时,它显示'TypeError: Cannot read 属性 'customService' of null'。如何在弹出模板中使用服务?
我认为您遇到了上下文问题。 getcustomcontent
里面的this
在执行渲染模板的时候值为null。
有一些选项可以设置函数的执行上下文。在下面的示例中,我使用 bind
.
popupTemplate: {
content: this.customPopupFunction.bind(this) // <- here
}
基本上,我表示当调用 customPopupFunction
时,它应该绑定到组件。这就是函数内部 this
起作用的原因,它在弹出模板内容中呈现组件的 madeBy
属性。
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from "@angular/core";
import { loadModules } from "esri-loader";
@Component({
selector: 'app-esri-map',
templateUrl: './esri-map.component.html',
styleUrls: ['./esri-map.component.scss']
})
export class EsriMapComponent implements OnInit, OnDestroy {
@ViewChild("mapViewNode", { static: true }) private mapViewEl: ElementRef;
view: any;
// to keep loaded esri modules
esriModules = {
layers: {
FeatureLayer: null
}
};
madeBy = '@cabesuon';
constructor() {}
async initializeMap() {
try {
// Load the modules for the ArcGIS API for JavaScript
const [
Map,
MapView,
FeatureLayer
] = await loadModules([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer"
]);
// save the modules on a property for later
this.esriModules.layers.FeatureLayer = FeatureLayer;
// Create the FeatureLayer
// USA counties layer
var countiesLayer = new FeatureLayer({
portalItem: {
id: "cd13d0ed1c8f4b0ea0914366b4ed5bd6"
},
outFields: ["*"],
minScale: 0,
maxScale: 0,
popupTemplate: {
content: this.customPopupFunction.bind(this)
}
});
// Configure the Map
const mapProperties = {
basemap: "streets",
layers: [countiesLayer]
};
const map = new Map(mapProperties);
// Initialize the MapView
const mapViewProperties = {
container: this.mapViewEl.nativeElement,
map,
zoom: 5,
center: [-107.3567, 37.7705]
};
this.view = new MapView(mapViewProperties);
await this.view.when(); // wait for map to load
return this.view;
} catch (error) {
console.error("EsriLoader: ", error);
}
}
ngOnInit() {
this.initializeMap().then(_ => {
// The map has been initialized
console.log("mapView ready: ", this.view.ready);
});
}
ngOnDestroy() {
if (this.view) {
// destroy the map view
this.view.container = null;
}
}
customPopupFunction(feature) {
return `<p>This is <strong>${feature.graphic.attributes.NAME}</strong> county, state of <strong>${feature.graphic.attributes.STATE_NAME}</strong></p>` +
`<p>This is an example of a custom popup content made by <span style="color:blue;">${this.madeBy}</span></p>`;
}
}
我正在尝试在服务返回结果的弹出模板中添加自定义内容。服务功能在 ngOninit() 或不属于弹出模板功能的自定义功能中工作。曾经在弹窗自定义模板功能中使用时,服务无法收集结果。
请找到下面的代码(只包含主要部分),导入自定义服务。
import { CustomService } from '../shared/service/custom.service';
constructor(private customService: CustomService){}
// Formation of the popup template
var popupTrailheads = {
title: "Unique id: {ID}",
content: this.getcustomcontent,
};
形成特征层弹出窗口应该来自这一层。
this.layer_fifteen = new FeatureLayer({
url: `${this.esriURL}/15`,
visible: true,
outFields: ['*'],
popupTemplate: popupTrailheads
});
下面的函数 getcustomcontent() 从服务中收集详细信息。
public getcustomcontent(feature) {
// the service code
this.customService.getIdDetails(popup_id).subscribe((posts) => {
//required to get the result from the service
}
}
当我使用 try-catch 时,它显示'TypeError: Cannot read 属性 'customService' of null'。如何在弹出模板中使用服务?
我认为您遇到了上下文问题。 getcustomcontent
里面的this
在执行渲染模板的时候值为null。
有一些选项可以设置函数的执行上下文。在下面的示例中,我使用 bind
.
popupTemplate: {
content: this.customPopupFunction.bind(this) // <- here
}
基本上,我表示当调用 customPopupFunction
时,它应该绑定到组件。这就是函数内部 this
起作用的原因,它在弹出模板内容中呈现组件的 madeBy
属性。
import { Component, OnInit, OnDestroy, ViewChild, ElementRef } from "@angular/core";
import { loadModules } from "esri-loader";
@Component({
selector: 'app-esri-map',
templateUrl: './esri-map.component.html',
styleUrls: ['./esri-map.component.scss']
})
export class EsriMapComponent implements OnInit, OnDestroy {
@ViewChild("mapViewNode", { static: true }) private mapViewEl: ElementRef;
view: any;
// to keep loaded esri modules
esriModules = {
layers: {
FeatureLayer: null
}
};
madeBy = '@cabesuon';
constructor() {}
async initializeMap() {
try {
// Load the modules for the ArcGIS API for JavaScript
const [
Map,
MapView,
FeatureLayer
] = await loadModules([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer"
]);
// save the modules on a property for later
this.esriModules.layers.FeatureLayer = FeatureLayer;
// Create the FeatureLayer
// USA counties layer
var countiesLayer = new FeatureLayer({
portalItem: {
id: "cd13d0ed1c8f4b0ea0914366b4ed5bd6"
},
outFields: ["*"],
minScale: 0,
maxScale: 0,
popupTemplate: {
content: this.customPopupFunction.bind(this)
}
});
// Configure the Map
const mapProperties = {
basemap: "streets",
layers: [countiesLayer]
};
const map = new Map(mapProperties);
// Initialize the MapView
const mapViewProperties = {
container: this.mapViewEl.nativeElement,
map,
zoom: 5,
center: [-107.3567, 37.7705]
};
this.view = new MapView(mapViewProperties);
await this.view.when(); // wait for map to load
return this.view;
} catch (error) {
console.error("EsriLoader: ", error);
}
}
ngOnInit() {
this.initializeMap().then(_ => {
// The map has been initialized
console.log("mapView ready: ", this.view.ready);
});
}
ngOnDestroy() {
if (this.view) {
// destroy the map view
this.view.container = null;
}
}
customPopupFunction(feature) {
return `<p>This is <strong>${feature.graphic.attributes.NAME}</strong> county, state of <strong>${feature.graphic.attributes.STATE_NAME}</strong></p>` +
`<p>This is an example of a custom popup content made by <span style="color:blue;">${this.madeBy}</span></p>`;
}
}