我如何从 Google 地图信息窗口调用 Angular2 函数?
How could I call a Angular2 function from a Google Map infowindow?
Google 地图以 javascript 方式集成,我想在信息窗口中调用 angular2 函数,如下面的代码。查看按钮的 infoContent
。
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent = '<button (click)="myFunction(' + locations[i].id + ')">Details ...</button>';
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
遗憾的是angular点击事件(click)="myFunction()"
无法做到。一定有别的办法。如果有人能指出我正确的方向,我将非常高兴。提前致谢。
更新(来自评论)
您可以使用 ElementRef
和 Renderer
来完成,但这不是问题所在。问题是获取按钮的引用(直接 DOM 元素引用或 ElementRef
)。您可以注入 private elRef:ElementRef
并使用 this.elRef.nativeElement.querySelector('infowindow button')
或类似的方法,但是如果您访问 elRef.nativeElement
,您将再次超出平台中立的范围,因为不应直接访问 nativeElement
,但是Renderer
的限制是只能调用方法,而不能在 return 中得到结果,你能做的只有这么多。
我会使用 Trigger event with infoWindow or InfoBox on click Google Map API V3 中所示的方法,然后检查 event.target
是否单击了您感兴趣的元素。
原创
如果您想在事件处理程序中访问 this.map
,您应该改用箭头函数
google.maps.event.addListener(marker, 'click', ((marker, i) => { // <<<===
return () => { // <<<===
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i)
否则this.
不会指向当前class实例
您可以在根 Window 中实例化对 ngZone 的引用并从信息中调用它Window.
首先您需要在构造函数中访问 NgZone:
constructor(public _ngZone: NgZone) { }
然后您可以在 window、ngOnInit、构造函数或某处设置一个指向您区域的指针,具体取决于您的代码:
window["angularComponentRef"] = { component: this, zone: this._ngZone };
最后,您可以使用 zone.run 从 infoWindow 回调到您的 Angular 函数,如下所示:
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent: string = '<button onclick="window.angularComponentRef.zone.run(() => {window.angularComponentRef.component.myFunction(\'' + locations[i].id + '\');})">Details ...</button>';
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
并且您可以在需要时清理函数以避免污染 window 命名空间,例如 ngOnDestroy:
window["angularComponentRef"] = null;
我搜索了很多并找到了答案:
您必须使用:$compile(htmlString)(scope)
在你的例子中试试这个:
var infoContent = '<button ng-click="myFunction(' + locations[i].id + ')">Details</button>';
var scope = angular.element(document.getElementById('anyElementId')).scope();
var compiled = $compile(htmlElement)(scope);
然后使用:
infowindow.setContent(compiled[0]);
哇啦!
这是我的解决方案。首先,我在信息 window 中将 id 设置为按钮。之后,我捕获了 'domready' 信息 window 事件,这意味着:所有 HTML 已被浏览器接收并解析到 DOM 树中,现在可以对其进行操作。然后使用 getElementById 访问按钮并添加事件 'click'。在这里你可以调用你在ts文件中定义的函数。
const infoWindowContent = '<h6>' + community.typeOfCommunity + '</h6>' +
'<p>' + community.address.name + ' ' + community.streetNumber + ', ' + community.city + '</p>' +
'<p>Manager: ' + community.manager.fullName + '</p>' +
'<button id="infoWindowButton">More info</button>';
const infoWindow = new google.maps.InfoWindow({
content: infoWindowContent
});
marker.addListener('click', () => {
infoWindow.open(this.map, marker);
});
infoWindow.addListener('domready', () => {
document.getElementById("infoWindowButton").addEventListener("click", () => {
this.myFunction();
});
});
请尝试此问题的完整解决方案。
var infowindow = new google.maps.InfoWindow({});
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent = '<div style="padding: 0.5em;">' +
'<h5 id="lt" style="font-size: 12px">'+locations[i].id +'</h5>'+
'<button id="btn" style="font-size: 8px;" >Click</button>'+
'</div>'
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
infowindow.addListener('domready', () => {
var val = document.getElementById('lt').innerHTML;
document.getElementById("btn").addEventListener("click", () => {
this.myFunction(val);
});
});
Google 地图以 javascript 方式集成,我想在信息窗口中调用 angular2 函数,如下面的代码。查看按钮的 infoContent
。
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent = '<button (click)="myFunction(' + locations[i].id + ')">Details ...</button>';
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
遗憾的是angular点击事件(click)="myFunction()"
无法做到。一定有别的办法。如果有人能指出我正确的方向,我将非常高兴。提前致谢。
更新(来自评论)
您可以使用 ElementRef
和 Renderer
来完成,但这不是问题所在。问题是获取按钮的引用(直接 DOM 元素引用或 ElementRef
)。您可以注入 private elRef:ElementRef
并使用 this.elRef.nativeElement.querySelector('infowindow button')
或类似的方法,但是如果您访问 elRef.nativeElement
,您将再次超出平台中立的范围,因为不应直接访问 nativeElement
,但是Renderer
的限制是只能调用方法,而不能在 return 中得到结果,你能做的只有这么多。
我会使用 Trigger event with infoWindow or InfoBox on click Google Map API V3 中所示的方法,然后检查 event.target
是否单击了您感兴趣的元素。
原创
如果您想在事件处理程序中访问 this.map
,您应该改用箭头函数
google.maps.event.addListener(marker, 'click', ((marker, i) => { // <<<===
return () => { // <<<===
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i)
否则this.
不会指向当前class实例
您可以在根 Window 中实例化对 ngZone 的引用并从信息中调用它Window.
首先您需要在构造函数中访问 NgZone:
constructor(public _ngZone: NgZone) { }
然后您可以在 window、ngOnInit、构造函数或某处设置一个指向您区域的指针,具体取决于您的代码:
window["angularComponentRef"] = { component: this, zone: this._ngZone };
最后,您可以使用 zone.run 从 infoWindow 回调到您的 Angular 函数,如下所示:
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent: string = '<button onclick="window.angularComponentRef.zone.run(() => {window.angularComponentRef.component.myFunction(\'' + locations[i].id + '\');})">Details ...</button>';
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
并且您可以在需要时清理函数以避免污染 window 命名空间,例如 ngOnDestroy:
window["angularComponentRef"] = null;
我搜索了很多并找到了答案:
您必须使用:$compile(htmlString)(scope)
在你的例子中试试这个:
var infoContent = '<button ng-click="myFunction(' + locations[i].id + ')">Details</button>';
var scope = angular.element(document.getElementById('anyElementId')).scope();
var compiled = $compile(htmlElement)(scope);
然后使用:
infowindow.setContent(compiled[0]);
哇啦!
这是我的解决方案。首先,我在信息 window 中将 id 设置为按钮。之后,我捕获了 'domready' 信息 window 事件,这意味着:所有 HTML 已被浏览器接收并解析到 DOM 树中,现在可以对其进行操作。然后使用 getElementById 访问按钮并添加事件 'click'。在这里你可以调用你在ts文件中定义的函数。
const infoWindowContent = '<h6>' + community.typeOfCommunity + '</h6>' +
'<p>' + community.address.name + ' ' + community.streetNumber + ', ' + community.city + '</p>' +
'<p>Manager: ' + community.manager.fullName + '</p>' +
'<button id="infoWindowButton">More info</button>';
const infoWindow = new google.maps.InfoWindow({
content: infoWindowContent
});
marker.addListener('click', () => {
infoWindow.open(this.map, marker);
});
infoWindow.addListener('domready', () => {
document.getElementById("infoWindowButton").addEventListener("click", () => {
this.myFunction();
});
});
请尝试此问题的完整解决方案。
var infowindow = new google.maps.InfoWindow({});
for (i = 0; i < locations.length; i++) {
let locLatLng = new google.maps.LatLng(locations[i].latitude, locations[i].longitude);
let infoContent = '<div style="padding: 0.5em;">' +
'<h5 id="lt" style="font-size: 12px">'+locations[i].id +'</h5>'+
'<button id="btn" style="font-size: 8px;" >Click</button>'+
'</div>'
marker = new google.maps.Marker({
position: locLatLng,
map: this.map
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(infoContent);
infowindow.open(this.map, marker);
};
})(marker, i));
}
infowindow.addListener('domready', () => {
var val = document.getElementById('lt').innerHTML;
document.getElementById("btn").addEventListener("click", () => {
this.myFunction(val);
});
});