2

Google map интегрирован javascript образом, и я хочу вызвать функцию углового2 внутри infowindow, как следующий код. Посмотрите на кнопку infoContent.Как я могу вызвать функцию Angular2 из окна Google Map?

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()" не может это сделать. Должен быть другой путь. Я был бы очень доволен, если кто-то может указать мне в правильном направлении. Заранее спасибо.

+0

В чем проблема с вашим 'addListener()'? Если 'this.map' не работает, как ожидалось, см. Мой ответ ниже. Есть что-то еще? Некоторое сообщение об ошибке, ...? –

+0

Открытие инфоиндуста отлично работает. Если я изменю путь от '(click)' до 'onclick', я получаю« Неотдача ReferenceError: myFunction не определен », но myFunction() находится внутри углового компонента. –

+0

Думаю, вы должны использовать делегирование событий. Вы также можете взглянуть на этот вопрос http://stackoverflow.com/questions/6378007/adding-event-to-element-inside-google-maps-api-infowindow – yurzui

ответ

2

обновление (с комментариями)

Вы можете сделать это с ElementRef и Renderer, но это не проблема. Проблема состоит в том, чтобы получить ссылку (ссылку прямого элемента 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. не будет указывать на текущий экземпляр класса

+0

Спасибо за ваш ответ. К сожалению, это не решает мою проблему. Я попробовал js-путь с помощью 'onclick' вместо' (click) ', но я получаю только« Uncaught ReferenceError: myFunction не определен ». –

+1

Я пропустил 'let infoContent = '';'. Angular2 не обрабатывает привязки, добавленные динамически, поэтому это не должно работать. Только привязки, добавленные к шаблонам компонентов, статически обрабатываются Angular2. Для динамически добавленных элементов вам нужно использовать 'addEventListener()'. –

+0

Благодарим за указание в правильном направлении. Угловой способ addEventListener(), похоже, проходит через 'ElementRef' и' Renderer'. Я попробую. –

3

You может сделать трюк, устанавливающий ссылку на ngZone в корневом окне и вызывая его изнутри infoWindow.

Прежде всего, необходимо, чтобы получить доступ к NgZone в конструкторе:

constructor(public _ngZone: NgZone) { } 

И тогда вы можете установить указатель обратно в зону в окне, на ngOnInit, конструктор или где-то, в зависимости от вашего кода:

window["angularComponentRef"] = { component: this, zone: this._ngZone }; 

Наконец, вы можете обратный вызов от infoWindow к вашей угловой функции с зоной.бежать, как это:

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

    } 

И вы можете очистить эту функцию при необходимости, чтобы избежать polute пространства имен окна, на ngOnDestroy, например:

window["angularComponentRef"] = null; 
-1

Я найти много и нашел ответ :

Вы должны использовать: $ компилировать (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]); 

Вала!

0

Это мое решение. Во-первых, я устанавливаю идентификатор кнопки в информационном окне. После этого я поймал событие «domready» для информационного окна, что означает: весь 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(); 
      }); 
     }); 

 Смежные вопросы

  • Нет связанных вопросов^_^