I am new to angular and I have searched intensively for a resolution to this issue but I can't quite seem to figure it out.
I have myRating
directive that is nested in ng-repeat
and that is nested in google maps api directive, html below:
<ui-gmap-google-map center='map.center' zoom='map.zoom'>
<ui-gmap-search-box template="searchbox.template" events="searchbox.events"></ui-gmap-search-box>
<ui-gmap-marker ng-repeat="marker in markers" click="marker.click" coords="marker" idKey="$index" icon="marker.icon"
events="marker.events">
<ui-gmap-window isIconVisibleOnClick="true" show="marker.showWindow" zIndex="">
<p class="gm-tooltip">
<a class="gm-name" href="{{marker.url}}">
{{marker.name}}<br>
<my-rating rating-value="marker.rating" max="5" read-only="true"></my-rating>
</a>
</p>
</ui-gmap-window>
</ui-gmap-marker>
Directive code:
angular.module('foodMap.directives')
.directive('myRating', function () {
return {
restrict: 'E',
template: '<div class="rating" ng-class="{readonly: readOnly}">' +
'<span ng-repeat="star in stars" class="star {{star.reverseIndex}}" ng-class="{fullstar: star.reverseIndex==ratingValue}" ng-click="toggle(star.reverseIndex, $event)"></span>' +
'</div>',
scope: {
ratingValue: '=',
max: '=',
readOnly: '@'
},
link: function (scope, element, attrs) {
scope.stars = [];
for (var i = scope.max; i > 0; i--) {
scope.stars.push({reverseIndex: i});
}
scope.toggle = function (reverseIndex, event) {
if (scope.readOnly)
return;
scope.ratingValue = reverseIndex;
//jQuery to remove
$('.star').removeClass('fullstar');
$(event.target).toggleClass('fullstar');
};
}
}
});
Controller
angular.module('foodMap.controllers')
.controller('MainCtrl', [
'$scope',
'bites',
function ($scope, bites) {
$scope.bites = bites.bites;
$scope.map = {
center: {
latitude: 51.5286416,
longitude: -0.1015987
},
zoom: 11
};
$scope.markers = [];
var createMarker = function (bite){
var marker = {
latitude: bite.location[0],
longitude: bite.location[1],
name: bite.name,
address: '',
icon: 'images/markers/restaurant.png',
url: '/#/bites/' + bite._id,
rating: bite.rating,
showWindow: false,
click: function() {
//not sure if this is the best solution
_.each($scope.markers, function(marker) {
marker.showWindow = false;
});
marker.showWindow = true;
}
}
$scope.markers.push(marker);
}
for (var i = 0; i < $scope.bites.length; i++){
createMarker($scope.bites[i]);
}
var events = {
places_changed: function (searchBox) {
var places = searchBox.getPlaces();
if (places) {
var lat = places[0].geometry.location.lat();
var lng = places[0].geometry.location.lng();
$scope.map.center.latitude = lat;
$scope.map.center.longitude = lng;
var address = places[0].address_components[0] && places[0].address_components[0].short_name || '';
var marker = {
latitude: lat,
longitude: lng,
name: places[0].name,
address: address,
icon: 'images/markers/star-3.png',
url: '/#/bites/',
rating: 5,
showWindow: true
}
$scope.markers.push(marker);
$scope.map.zoom = 15;
}
}
}
$scope.searchbox = { template:'searchbox.tpl.html', events: events };
}
]);
So the problem is that that currently I have 3 markers
in my db and ng-repeat
loops through the collection twice so myRating
directive is called 6 times. When I console.log(ratingValue)
, during the first loop the values are correct, but when it loops the second time all ratingValue
values are undefined
.
From all the research I have done, as far as I understand, angular performs dirty-checking to figure out what has changed, so that's why two loops? But I don't understand why I'm loosing these values that are bind correctly in the first loop.
Sorry, I hope that is clear enough, I would appreciate any pointers!