Search code examples
javascriptangularjsangularjs-scope

Hi, I do not use ng-click event in my Controller with Style Guide Definitions


I can't use ng-click event in my Controller with style guide definitions.

(function() {
    'use strict';

    angular.module('starter.controllers')
        .controller('MapsCtrl', maps);

    function maps($ionicLoading, $compile, $stateParams) {
        var vm = this;

        var citiesList = [
            {
                id: 1,
                city: 'City One',
                desc: 'This is the best city in the world!',
                lat: -25.5511123,
                long: -49.4059869
            },
            {
                id: 2,
                city: 'City Two',
                desc: 'This city is aiiiiite!',
                lat: -25.481642,
                long: -49.293805
            },
            {
                id: 3,
                city: 'City Three',
                desc: 'This is the second best city in the world!',
                lat: -25.5867087,
                long: -49.1551404
            },
            {
                id: 4,
                city: 'City Four',
                desc: 'This city is live!',
                lat: -25.424667,
                long: -49.1605463
            }
        ];

        var _siteLatLng = new google.maps.LatLng(-25.5511123, -49.4059869); // city One default
        var _hospitalLatLng = new google.maps.LatLng(-25.481642, -49.293805); // city Two default

        var _mapOptions = {
            zoom: 4,
            center: _siteLatLng,
            mapTypeId: google.maps.MapTypeId.TERRAIN
        };

        var _map = new google.maps.Map(document.getElementById('map'), _mapOptions);
        var _markers = [];

        var createMarker = function(info) {
            var _marker = new google.maps.Marker({
                map: _map,
                position: new google.maps.LatLng(info.lat, info.long),
                title: info.city
            });
            _marker.content = '<div class="infoWindowContent">' + info.desc + '</div>';

            var _htmlInfo = '<div><a ng-click="vm.clickTest(' + info.id + ')"><h2>' + _marker.title + '</h2></a>' + _marker.content + "</div>";
            var _compiled = $compile(_htmlInfo)(vm);

            var _infoWindow = new google.maps.InfoWindow({
                content: _compiled[0]
            });

            google.maps.event.addListener(_marker, 'click', function() {
                // infoWindow.setContent(_htmlInfo);
                _infoWindow.open(_map, _marker);
            });

            _markers.push(_marker);
        }

        for (var i = 0; i < citiesList.length; i++) {
            createMarker(citiesList[i]);
        };

        // BEGIN -- Destionation
        var _directionsService = new google.maps.DirectionsService();
        var _directionsDisplay = new google.maps.DirectionsRenderer();

        var _request = {
            origin: _siteLatLng,
            destination: _hospitalLatLng,
            travelMode: google.maps.TravelMode.DRIVING
        };
        _directionsService.route(_request, function(response, status) {
            if (status == google.maps.DirectionsStatus.OK) {
                _directionsDisplay.setDirections(response);
            }
        });

        _directionsDisplay.setMap(_map);
        // END -- Destination

        // Declare variables as vm
        vm.map = _map;
        vm.markers = _markers;


        vm.centerOnMe = function() {
            if (!vm.map)
                return;

            vm.loading = $ionicLoading.show({
                content: 'Getting current location...',
                showBackdrop: false
            });
            navigator.geolocation.getCurrentPosition(function(pos) {
                vm.map.setCenter(
                    new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude)
                );
                $ionicLoading.hide();

                var _position = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
                var _marker = new google.maps.Marker({
                    map: vm.map,
                    position: _position,
                    title: 'You are here!',
                    icon: 'images/places/place_black.png'
                });

                console.log( _position );
                console.log( pos);
                console.log( vm.map );

                var _htmlInfo = '<div><h1>You!</h1> Content text.</div>';
                var _compiled = $compile(_htmlInfo)(vm);
                var _infoWindow = new google.maps.InfoWindow({
                    content: _compiled[0]
                });

                google.maps.event.addListener(_marker, 'click', function() {
                    // infoWindow.setContent(_htmlInfo);
                    _infoWindow.open(_map, _marker);
                });
            },
            function(error) {
                alert('Unable to get location: ' + error.message);
            });
        };

        vm.clickTest = function(_id) {
            console.log('Clicked!!!', _id);

            alert(citiesList[_id - 1].city + ' is clicked! :D');
        };
    };

})();

Console error:

Uncaught TypeError: scope.$apply is not a function
(anonymous function)    @   ionic.bundle.js:53438
eventHandler    @   ionic.bundle.js:11713


//ionic.bundle.js  line: 53438

/**
 * @private
 */
.factory('$ionicNgClick', ['$parse', function($parse) {
  return function(scope, element, clickExpr) {
    var clickHandler = angular.isFunction(clickExpr) ?
      clickExpr :
      $parse(clickExpr);

    element.on('click', function(event) {
      scope.$apply(function() {  // (x) Uncaught TypeError: scope.$apply is not a function
        clickHandler(scope, {$event: (event)});
      });
    });

    // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
    // something else nearby.
    element.onclick = noop;
  };
}])

Please, help me, if possible! Thanks!


Screenshot

If I click in title from Window, return the error in the console.


Solution

  • Inside the controller used as ControllerAs you reference the scope with this.

    try something like:

    var _compiled = $compile(_htmlInfo)(this);
    ...
    this.clickTest =...
    

    See here for more details