我如何从Google Map infowindow调用Angular2函数?

时间:2016-09-28 06:25:49

标签: javascript google-maps-api-3 angular google-maps-markers

Google地图是以javascript方式集成的,我想在infowindow中调用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));

}

不幸的是,角点击事件(click)="myFunction()"无法做到。必须有另一种方式。如果有人能指出我正确的方向,我会很高兴。提前谢谢。

5 个答案:

答案 0 :(得分:6)

你可以在root用户窗口中实现对ngZone的引用,然后从infoWindow中调用它。

首先,您需要在构造函数中访问NgZone:

 constructor(public _ngZone: NgZone) {    }

然后你可以在窗口, 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));

    }

您可以在需要时清除该功能,以避免在 ngOnDestroy 上对窗口名称空间进行轮询:

 window["angularComponentRef"] = null;

答案 1 :(得分:3)

更新(来自评论)

您可以使用ElementRefRenderer执行此操作,但这不是问题所在。问题是获得按钮的引用(直接DOM元素引用或ElementRef)。您可以注入private elRef:ElementRef并使用this.elRef.nativeElement.querySelector('infowindow button')或类似内容,但如果您访问elRef.nativeElement,则您再次脱离平台中立领域,因为nativeElement不应该直接访问,但是由于Renderer的限制只能调用方法但永远不会得到结果,所以只能做很多事情。

我会使用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.将不会指向当前的类实例

答案 2 :(得分:0)

这是我的解决方案。首先,我在信息窗口中将id设置为按钮。之后,我抓住了信息窗口的'domready'事件,这意味着:所有HTML都已被浏览器接收并解析为DOM树,现在可以对其进行操作。然后使用getElementById访问按钮并添加事件'click'。在这里,您可以调用ts文件中定义的函数。

Usuario             Free days  Baja Permisos
==============    ============  ==== ========
Usuario1                10        1        0

答案 3 :(得分:0)

请针对此问题尝试使用完整的解决方案。

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);
        });
    });

答案 4 :(得分:-1)

我经常搜索并找到答案:

您必须使用:$ compile(htmlString)(范围)

在你的例子中试试这个:

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]);

瓦剌!