Coo
Coo

Reputation: 1882

Angular Google Maps, Directive inside Info Window isn't binding data

I'm using Angular google Maps trying to get an info window working. When a marker is selected, the window is placed there and shown. Its content is some text and also some directives. The directives inside even work, except for when I try to bind some data its attributes.

In this case I'm having a rating directive (shows a bunch of stars) that takes a number attribute, as so:

<div stars number="person.rating"></div>

Note that this directives works just fine in a couple of other places in my app. Also, when I replace person.rating' for3, the directive renders perfectly. when I useperson.rating` outside of this div, it returns a number as expected.

Only when I combine the person.rating inside the number attribute, inside the window directive, do things go awry:

<ui-gmap-google-map center='map.center' class="big-maps" options='map.options' events="map.events" zoom='map.zoom'>
    <ui-gmap-window coords="selectedCoords" show="windowOptions.visible" closeClick="closeWindow">
    <div>
        Name: {{person.firstName}}, Rating: {{person.rating}} <!-- these work just fine. -->
        <div> So here we are. {{person.rating}}</div> <!-- this also works just fine. -->
        <div stars number="3"></div> <!-- Even this works fine. -->
        <div stars number="person.rating"></div> <!-- But this doesn't... -->
    </div>
    </ui-gmap-window>

    <ui-gmap-markers
    models='markers'
    idKey='id'
    coords="'coords'"
    icon="'icon'"
    options="'options'"
    doCluster="false"
    click="showWindow"
    >
    </ui-gmap-markers>
</ui-gmap-google-map>

The directive:

ndtApp.directive('stars', stars);
function stars() {
    return {
        restrict: "AE",
        replace: 'true',
        scope: {
            number: "=",
            size: "@"
        },
        templateUrl: "shared/stars/stars.html",
        controller: controller
    };
}

function controller($scope){
    $scope.getEmptyStarsArray = getEmptyStarsArray;
    $scope.getStarsArray = getStarsArray;
    $scope.ratingSize = "";

    activate();

    function activate(){
        if ($scope.size == 'sm'){
            $scope.ratingSize = 'rating-sm';
        } else if ($scope.size == 'lg'){
            $scope.ratingSize = 'rating-lg';
        } 

        console.log($scope.number);

    }

    function getEmptyStarsArray(){
        if ($scope.number === undefined) return 0;

        var rating = Math.round($scope.number);
        if (rating > 4) return null;
        return new Array(5 - rating);
    }

    function getStarsArray(){
        if ($scope.number === undefined) return 0;

        var rating = Math.round($scope.number);
        if (rating === 0) return null;
        if (rating > 5) return new Array(5);
        return new Array(rating);
    }
}

stars.html:

<div class="stars">
    <span ng-repeat="i in getStarsArray() track by $index" class="{{ratingSize}} rating glyphicon glyphicon-star"></span><span ng-repeat="i in getEmptyStarsArray() track by $index" class="{{ratingSize}} rating glyphicon glyphicon-star-empty"></span>
</div>

Any help is highly appreciated!

Upvotes: 1

Views: 613

Answers (1)

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59368

It seems directive scope property is not getting bound, try to change scope for number property from number: "=" to number: "@" and directive initialization from <div stars number="person.rating"></div> to <div stars number="{{person.rating}}"></div>

Below is provided a working similar example:

var appMaps = angular.module('appMaps', ['uiGmapgoogle-maps']);
appMaps.controller('mainCtrl', function($scope,uiGmapIsReady) {
    $scope.map = {
        center: { latitude: 40.1451, longitude: -99.6680 },
        zoom: 4,
        options: { scrollwheel: false }
    };

    $scope.windowOptions = { visible: false };

    var getRandomLat = function() {
        return Math.random() * (90.0 + 90.0) - 90.0;
    };
    var getRandomLng = function () {
        return Math.random() * (180.0 + 180.0) - 180.0;
    };  


    var getRandomRating = function() {
         return Math.floor(Math.random() * 11);
    };

    

    var createRandomMarker = function(i) {
        var ret = {
            latitude: getRandomLat(),
            longitude: getRandomLng(),
            title: 'Hotel #' + i,
            show: false,
            id: i
        };
        return ret;
    };



    $scope.onClick = function(marker, eventName, model) {
        $scope.windowOptions.visible = true;
        $scope.selectedHotel = model;
        $scope.rating = { number: getRandomRating()}; 
    };

    $scope.closeWindow = function () {
        $scope.windowOptions.visible = false;
    };

   
    $scope.hotels = [];
    for (var i = 0; i < 256; i++) {
        $scope.hotels.push(createRandomMarker(i));
    }

});


appMaps.directive('rating',
function() {
    return {
        restrict: "AE",
        replace: true,
        scope: {
            //number: "=",
            number: "@"
        },
        controller: ratingController,
        //template: '<div >Rating: {{ ::number }}</div>',
        template: function(tElem, tAttrs){
          return '<div class="rating"> Rating:' + tAttrs.number + '</div>';
        }
    };
});


function ratingController($scope){
   console.log($scope.number);
}
html, body, #map_canvas {
    height: 100%;
    width: 100%;
    margin: 0px;
}

#map_canvas {
    position: relative;
}

.angular-google-map-container {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: 0;
}
<script src="https://code.angularjs.org/1.3.14/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
<script src="http://rawgit.com/angular-ui/angular-google-maps/2.0.X/dist/angular-google-maps.js"></script> 

<div id="map_canvas" ng-app="appMaps" ng-controller="mainCtrl"> 
        <ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="options" events="map.events">
            <ui-gmap-window coords="selectedHotel" show="windowOptions.visible" closeclick="closeWindow">
                <div>
                    <div>{{selectedHotel.title}}</div>
                    <div rating number="{{rating.number}}"></div> 
                </div>
            </ui-gmap-window>
            <ui-gmap-markers models="hotels" coords="'self'" icon="'icon'" click="onClick">
            </ui-gmap-markers>
        </ui-gmap-google-map>
</div>

Upvotes: 2

Related Questions