2013-07-15 4 views
13

Używam Angular.JS i Leaflet.JS dla mapy w mojej lokalizacji, która ma znaczniki map z powiązanymi do nich wyskakującymi okienek popup. Muszę użyć rozpiętości z dwiema różnymi ikonami (jedną pokazaną w kodzie poniżej), którą możesz kliknąć, aby wywołać różne funkcje, i ng-class, aby zmienić klasę, jeśli spełnione są określone warunki. To jest mój kod:Jak korzystać z dyrektyw kątowych ng-click i ng-class wewnątrz Okienko znacznika popup wyskakujące

var marker = L.marker([51.5, -0.09], {icon: blueIcon}).bindPopup('<br><span ng-class="thumbsUpClass(' + hotelsSelectedDates[i]['hotels'][s] + ')" ng-click="addChoice(' + hotelsSelectedDates[i]['hotels'][s] + ',' + hotels + ')"><span class="popup-container"><span class="icon-stack thumbs-up-stack"><i class="icon-sign-blank icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span>'); 

Jednak kiedy sprawdzać element uzyskać to:

<span ng-class="thumbsUpClass([object Object])" ng-click="addChoice([object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object])"><span class="popup-container"><span class="icon-stack thumbs-up-stack"><i class="icon-sign-blank icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span> 

NG-click powinien wysłać tę funkcję zarówno konkretnego przedmiotu oraz tablicę obiektów, ale gdy klikam ikona nic się nie dzieje. W moich badaniach znalazłem, że wyskakujące okienko zapobiega rozprzestrzenianiu się zdarzenia (more info, ale nie jestem pewien, jak go zastąpić lub naprawić, aby działało z kątem.) Czy ktoś ma pomysł, jak to zrobić?

AKTUALIZACJA :

Od nG-click/klasa ocenić ciąg Naprawiłem zmienne być tak:

$scope.item = hotelsSelectedDates[i]['hotels'][s] 
$scope.set = hotels 
var marker = L.marker([51.5, -0.09], {icon: blueIcon}).bindPopup('<br><span ng-class="thumbsUpClass(item)" ng-click="addChoice(item,set)"><span class="popup-container"><span class="icon-stack thumbs-up-stack"><i class="icon-sign-blank icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span>'); 

html następnie wychodzi poprawnie:

<span ng-class="thumbsUpClass(item)" ng-click="addChoice(item,set)"><span class="popup-container"><span class="icon-stack thumbs-up-stack"><i class="icon-sign-blank icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span> 

Jednak po kliknięciu ikony nic się nie dzieje i nie wygląda na to, że wywoływane są funkcje. Ktoś ma jakąś wskazówkę, dlaczego tak się stało?

+1

Postaraj się, aby przykłady kodu pasować do szerokości strony, więc nie trzeba przewijać lub wykorzystanie plunkr, to jest nieczytelne bez dużego wysiłku. – Maarten

Odpowiedz

26

Twój problem wynika z faktu, że ręcznie tworzysz DOM, który nie został skompilowany przez AngularJS.

W takich przypadkach należy ręcznie skompilować i połączyć element.

kod wyglądałby następująco:

var html = '<br><span ng-class="thumbsUpClass(item)" ' + 
    'ng-click="addChoice(item,set)"><span class="popup-container"><span ' + 
    'class="icon-stack thumbs-up-stack"><i class="icon-sign-blank ' + 
    'icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span>', 
    linkFunction = $compile(angular.element(html)), 
    newScope = $scope.$new(); 

newScope.item = hotelsSelectedDates[i]['hotels'][s] 
newScope.set = hotels 
var marker = L.marker([51.5, -0.09], {icon: blueIcon}).bindPopup(linkFunction(newScope)[0]); 

Oto biorę swój ciąg HTML i zacznę poprzez przekształcenie go w DOM. Ponieważ AngularJS je DOM, a nie ciągi.

angular.element(html) 

Następnie kompiluję ten DOM w funkcję łączenia za pomocą usługi $ compile.

linkFunction = $compile(angular.element(html)); 

Po wykonaniu, funkcja ta zwróci jQuery DOM drzewo w pełni kontrolowane przez kątowe, działa w zakresie dajesz to jako argument. Oto, co tutaj robię:

linkFunction(newScope) 

Należy pamiętać, że zakres, który podaję, to zakres podrzędny zakresu $ zakres. Bez tego można by dzielić ten sam zakres pomiędzy wszystkimi wyskakującymi okienkami, a to nie byłby dobry pomysł. Tworzenie nowego zakresu zostało zrobione w deklaracji var

newScope = $scope.$new() 

Od czemu można uzyskać rzeczywiste węzła DOM

linkFunction(scope)[0] 

i przekazać je do Ulotka

.bindPopup(linkFunction(newScope)[0]); 

i gotowe !

Aby uzyskać więcej informacji, zapoznaj się z dokumentem compiler.

edit: poprawione kwestie dotyczące zakresu

0

Pracowałem na tym szczególnym rodzaju problemu, do wystąpienia funkcję przed kliknięciem wewnątrz popup. Użyłem dyrektywy kątowej-ulotki, w której nie mogłem wykonać kompilacji $ $, ponieważ było już wewnątrz kompilacji $ $ i utworzyłem odwołanie cykliczne. To, co zrobiłem, było następujące.

$scope.markers[$scope.asset_table[imc]['asset']['_id']['$oid']]={ 
         lat:$scope.asset_table[imc]['last_data']['loc']['coordinates'][1], 
         lng:$scope.asset_table[imc]['last_data']['loc']['coordinates'][0], 
         focus:true, 
         message:"<h4>"+$scope.asset_table[imc]['asset']['name']+"</h4> 
         <span class='btn btn-danger' 
         onclick='detailView()';>View Details</span>", 
         //message: linkFunction, /*I discarded this as it was creating circular reference*/ 
         icon: { 
          iconUrl: $scope.icon, 
          iconSize: [30, 30], 
          iconAnchor: [15, 15], 
          popupAnchor: [0, 0], 
          shadowUrl: $scope.icon, 
          shadowSize:[0,0], 
          iconAngle:$scope.asset_table[imc]['last_data']['bearing'] 
         } 
        }; 

A poniżej tym, viewDetail function() została wywołana

detailView = function(){ 
    //alert("Test"); 
    $rootScope.$broadcast('asset.details',$scope.asset_table); 
} 

więc musiałem użyć tradycyjnego JavaScript wewnątrz kanciasty uniknąć skomplikowania kołowej łączenia.

+0

Pamiętaj, co tutaj zrobiłeś. W jaki sposób uzyskać dane istotne dla konkretnego okna popup z twojej tabeli aktywów_zasobów? – mstreffo

+0

Każdy plik asset_table [imc] ma unikalny komunikat, w którym jest przycisk bootstrapu oparty na rozpiętości z onclick zamiast ng-click, który uruchamia funkcję detailView(), która jest napisana prostym językiem javascript. To wyzwala emisję. – tor9ado

9

Można użyć nowego wsparcia dla Kątowymi treści w kątowa-ulotka-dyrektywy:

var html = '<br><span ng-class="thumbsUpClass(item)" ' + 
    'ng-click="addChoice(item,set)"><span class="popup-container"><span ' + 
    'class="icon-stack thumbs-up-stack"><i class="icon-sign-blank ' + 
    'icon-stack-base"></i><i class="icon-thumbs-up"></i></span></span></span>'; 

... 

$scope.markers.push({ lat: ..., 
         lng: ..., 
         message: html, 
         getMessageScope: function() { return $scope; },   
}); 
+0

Działa to naprawdę dobrze! Zastanawiam się, dlaczego nie ma żadnego przykładu na stronie ... Jednak "compileMessage" może również być ustawione na "true" w obiekcie, który przekazujesz do metody 'push' w najnowszej wersji wtyczki. Działa to również tylko dla znaczników, a nie ścieżek itp. – sibbl

0

Jestem trochę późno na ten temat, ale miałem podobną sytuację i chciałem podzielić się moją rozwiązanie.

Załóżmy, że masz jakiś html, który chcesz dodać do swojego wyskakującego okienka, po prostu dodaj do niego "id".

var html = '<a id="popup" href="" ng-model="featureSelected" ng-click="cherryPickPin(featureSelected)">cherry pick this pin</a>'; 

teraz wszystko, co musisz zrobić to:

var popupElement = $('#popup'); // grab the element (make sure that it exists in the DOM) 
popupElement = $compile(popupElement)($scope); // let angular know about it 
0

przyjechałem na tym stanowisku, ponieważ szukałem rozwiązania tego problemu na Ionic/Cordova (integracja mapy w aplikacji mobilnej).

Problem polega na tym, że funkcja $ compute nie działa, ponieważ działa z lite jQuery. Tak więc jedyna droga i najwyraźniej najprostsza, aby to działało, to kod zaproponowany przez Davida (Dziękuję bardzo, kolego!).

W moim kodu, wygląda to tak:

$scope.map.markers[i] = { 
    lat: parseFloat(place.latitude), 
    lng: parseFloat(place.longitude), 
    message: htmlPopupContent, 
    getMessageScope: function() { return $scope; }, 
    focus: true, 
    draggable: false 
}; 

Nadzieja to może pomóc!

0

znalazłem tę odpowiedź pomoc dla mapbox-GL-js i kątowe:

var html = '<button ng-click="fn()">Click Me</button>'; 
var compiledHtml = $compile(html)($scope); 
var popup = new mapboxgl.Popup() 
.setLngLat([-91.874, 42.760]) 
.setDOMContent(compiledHtml[0]) 
.addTo(map); 

Enable ng-click on a popup (mapbox)