AngularJS и иерархия охвата

0

У меня возникли проблемы с пониманием иерархии областей в вложенном сценарии.

Я использую UI-маршрутизатор. В моем домашнем шаблоне есть;

ui-view and a directive 'gmap-locator'.   
 ui-view loads the following template/controller as default  'LocationFilter.Html/locationfilter',  within which I am nesting a directive A
        within which I am nesting a directive B
          within which I am nesting a directive C
          ... From C  I am calling a function 'funcXYZ()' on an ng-click.

У меня есть мой "funcXYZ()", объявленный на домашнем контроллере и "gmap-locator" директивным контроллером.
Я ожидал, что "funcXYZ()" в домашнем контроллере будет вызван, но, к моему удивлению, "funcXYZ()" в контроллере gmap-locator вызывается до тех пор, пока я не прокомментирую это (тогда он предлагает функцию домашнего контроллера).

Он не попадает в правильную иерархию проповеди, по крайней мере, с моим пониманием.. любые мысли?

Я использую UIRouter, и моя маршрутизация выглядит так:

app.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('/searchModeList');
    $stateProvider
        .state('home', {
            url: '/',
            templateUrl: '/templates/Index.html',
            controller: 'homeController'
        })
        .state('home.searchModeList', {
            url: 'searchModeList',
            templateUrl: '/templates/SearchModeList.html',
            controller: 'searchModeListController'
        })
        .state('home.countyList', {
            url: 'countyList',
            templateUrl: '/templates/countyList.html',
            controller: 'countyListController'
        })
        .state('home.locationFilters', {
            url: 'locationFilters',
            templateUrl: '/templates/locationFilters.html',
            controller: 'locationFiltersController'
        })
});

Код директивы Gmap_locator.. Извините Его длинный/грубый и должен быть реорганизован.. но только для справочной цели..

app.directive('gmapLocator', function ($timeout, $modal, AppModesService,$rootScope) {
    var link = function (scope, element, attrs) {
        scope.mapParameters = {
            mapContainerID: 'mappe',
            initialSettings: {
                zoom: 10,
                Lat: 39.1686269,
                Lng: -76.7757216
            },
            markerIcon: '../Content/Images/roundblue.png',
            markerSelectedIcon: '../Content/Images/orangeround.png',
            markerZoomIcon: '../Content/Images/roundgreen.png',
            crashIcon: '../Content/Images/redcrossconfirm.png'
        }
        var map, mapOptions, bounds, markers = [], previousSelectedMarker, previousCrashLocation, mapClickListener,
            prevLabel, line, mapZoomMode = 'init', lineCoordinates;
        var lat = scope.mapParameters.initialSettings.Lat;
        var lng = scope.mapParameters.initialSettings.Lng;
        mapOptions = {
            mapTypeId : google.maps.MapTypeId.ROADMAP,
            center: new google.maps.LatLng(lat, lng),
            zoom: scope.mapParameters.initialSettings.zoom
        };
        function initMap() {
            map = new google.maps.Map(document.getElementById(scope.mapParameters.mapContainerID), mapOptions);
        }
        $timeout(function () { initMap() },100);
        var mapFullZoom = function (map,position) {
            (new google.maps.MaxZoomService()).getMaxZoomAtLatLng(position, function (response) {
                var zoom = 19;
                if (response.status == google.maps.MaxZoomStatus.OK) {
                    zoom = response.zoom;
                }
                map.setZoom(zoom);
                map.setMapTypeId(google.maps.MapTypeId.HYBRID);
            });
        }
        var setMarker = function (position,title,id) {
            var marker,
                markerClickTimer, currentZoom,currentZoom;
            scope.zoomLevel = 'normal';
            scope.mapZooms = {};
                markerOptions = {
                    position: position,
                    map: map,
                    title: title,
                    id: id,
                    icon: scope.mapParameters.markerIcon
                };
                var markerClickZoomIncrement = 0;
                var referencePointsCount = scope.referencePoints.length;
                if (referencePointsCount < 15) markerClickZoomIncrement = 1;
                else if((referencePointsCount >15) && (referencePointsCount < 50)) markerClickZoomIncrement = 2;
                else if(referencePointsCount>50) markerClickZoomIncrement =4;
            marker = new google.maps.Marker(markerOptions);
            google.maps.event.addListener(marker, 'click', function () {
                var element = this;
                //scope.searchBy.keyword = null; // To reset the Reference Point filter search textbox
                //scope.pointNotFound = false; // To reset the PointNotFound button selection
                scope.referencePointChanged();// call parent scope function
                scope.referencePointSelectMode = 'map';
                AppModesService.setResult('Lat',marker.position.lat());
                AppModesService.setResult('Long', marker.position.lng());
                map.panTo(marker.position);
                if ((previousSelectedMarker) && (previousSelectedMarker.id != marker.id)) {
                    previousSelectedMarker.setIcon(scope.mapParameters.markerIcon);
                    mapZoomMode = 'init';
                }
                if ((mapZoomMode == 'init') || (previousSelectedMarker.id != marker.id)) {
                        mapZoomMode = 'selected';
                        scope.selectIntersectionId = element.id;
                        AppModesService.setSelectedReferencePoint(element.id);
                        AppModesService.setResult('ReferenceRoadName', element.title);
                        clearMapClickListener();
                        clearCrashMarker();
                        if (!scope.mapZooms.initZoomLevel) {
                            currentZoom = map.getZoom();
                            scope.mapZooms.initZoomLevel = currentZoom;
                            scope.mapZooms.initCenter = map.getCenter();
                        }
                        if (map.getMapTypeId() !== google.maps.MapTypeId.ROADMAP) {
                            map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
                            map.setZoom(scope.mapZooms.initZoomLevel + markerClickZoomIncrement);
                        }
                        if (scope.zoomLevel == 'normal') {
                            map.setZoom(currentZoom + markerClickZoomIncrement);
                            scope.zoomLevel = 'lightZoom';
                        }
                        element.setIcon(scope.mapParameters.markerSelectedIcon);
                        previousSelectedMarker = element;
                }
                else if(previousSelectedMarker.id == marker.id){
                    if (mapZoomMode == 'selected') {
                        mapZoomMode = 'confirmed';
                        map.setZoom(30);
                        map.setMapTypeId(google.maps.MapTypeId.HYBRID);
                        element.setIcon(scope.mapParameters.markerZoomIcon);
                        setMapClickEvent();
                    }
                }
                $timeout(function () {
                    scope.$apply();
                });
            });
            bounds.extend(position);
            markers.push(marker);
        };
        var setMapClickEvent = function () {
            mapClickListener = google.maps.event.addListener(map, 'click', function (event) {
                clearCrashMarker();
                previousCrashLocation = new google.maps.Marker({
                    position: event.latLng,
                    map: map,
                    title: 'Crash Location',
                    icon: scope.mapParameters.crashIcon,
                    draggable: true
                });
                if ((!AppModesService.getMissingPointMode()) && (!AppModesService.getMissingPointMode())) {
                    prevLabel = document.getElementsByClassName('GLabel');
                    clearLabel();
                    label = new Label({
                        map: map
                    });
                    var offset = getOffset(event.latLng, previousSelectedMarker.position);
                    label.bindTo('position', previousCrashLocation, 'position');
                    label.set('text', offset);
                    lineCoordinates = getLineCoordinates(event);
                    clearLine();
                    drawLine(lineCoordinates);
                    AppModesService.setResult('Distance', offset);
                }
                setCrashLatLong(event.latLng);
                crashMarkerClickListener = google.maps.event.addListener(previousCrashLocation, 'click', function (event) {
                    if ((!scope.pointNotFound) && (!scope.routeNotFound)) scope.openVerifyForm();
                    else scope.openMissingForm();
                });
                google.maps.event.addListener(previousCrashLocation, 'dragstart', function () {
                    if (!scope.pointNotFound) {
                        clearLine();
                        label.set('text', '_ _ _');
                    }
                });
                google.maps.event.addListener(previousCrashLocation, 'dragend', function (event) {
                    if (!scope.pointNotFound) {
                        var offset = getOffset(event.latLng, previousSelectedMarker.position);
                        label.set('text', offset);
                        lineCoordinates = getLineCoordinates(event);
                        clearLine();
                        drawLine(lineCoordinates);
                        AppModesService.setResult('Distance', offset);
                    }
                    setCrashLatLong(event.latLng);
                });
                // Set crash location data //
            });
        }

        var clearMapClickListener = function () {
            if (mapClickListener) {
                google.maps.event.removeListener(mapClickListener);
            }
        }
        var setCrashLatLong = function (latLng) {
            AppModesService.setResult('CrashLat', latLng.lat());
            AppModesService.setResult('CrashLong', latLng.lng());
        }
        var getLineCoordinates = function (event) {
            return lineCoordinates = [
                                   event.latLng,
                                   previousSelectedMarker.position
            ];
        }
        var drawLine = function (lineCoordinates) {
            var lineSymbol = {
                path: 'M 0,-1 0,1',
                strokeOpacity: .8,
                scale: 6,
                strokeWeight: 2,
                strokeColor: 'red'
            };
            line = new google.maps.Polyline({
                path: lineCoordinates,
                strokeOpacity: 0,
                icons: [{
                    icon: lineSymbol,
                    offset: '0',
                    repeat: '20px'
                }],
                map: map
            });
        }
        var clearCrashMarker = function () {
            if (previousCrashLocation) {
                if (crashMarkerClickListener) {
                    google.maps.event.removeListener(crashMarkerClickListener);
                }
                previousCrashLocation.setMap(null);
            }
            clearLabel();
            clearLine();
        }
        var createLabel = function () {
            label = new Label({
                map: map
            });
        }
        var clearLabel = function () {
            if ((prevLabel != null) && (prevLabel.length > 0)) {
                prevLabel[0].parentNode.removeChild(prevLabel[0]);
            }
        }
        var clearLine = function () {
            if (line != null) {
                line.setMap(null);
            }
        }
        Number.prototype.toRad = function () { return this * Math.PI / 180; }
        var getOffset = function (eventPosition, markerPosition) {
            var result = -1;
            var lat1 = eventPosition.lat(),
                lon1 = eventPosition.lng(),
                lat2 = markerPosition.lat(),
                lon2 = markerPosition.lng();

            //var R = 6371; // km
            var R = 3961; // miles
                var dLat = (lat2 - lat1).toRad();
                var dLon = (lon2 - lon1).toRad();
                var lat1 = lat1.toRad();
                var lat2 = lat2.toRad();

                var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
                        Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
                var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
                var d = R * c;
                if (d > 1) result = d.toFixed(2) + ' miles(s)';
                else result = (d * 1760).toFixed(2) + ' yards(s)'
            return result; // yards and miles
        }
        var getMarkerIndexById = function (id) {
            var referencePointIndex = scope.referencePoints.map(function (element) {
                return element.id
            }).indexOf(id);
            return referencePointIndex;
        }
        scope.setpointNotFound = function () {
            AppModesService.setRouteNotFound(false);
            AppModesService.setPointNotFound(true);
            resetMarkers();
            map.fitBounds(bounds);
        }
        var resetMarkers = function () {
            mapZoomMode = 'init';
            if (previousSelectedMarker) {
                previousSelectedMarker.setIcon(scope.mapParameters.markerIcon);
            }
            clearCrashMarker();
            clearLine();
            clearLabel();
            scope.selectIntersectionId = null;
            previousSelectedMarker = null;
            map.setMapTypeId(google.maps.MapTypeId.ROADMAP)
        }
        var removeMarkers = function () {
            for (var markerItem in markers) {
                markerItem.setMap(null);
            }
        }
        var resetMap = function () {
            resetMarkers();
            initMap();
        }
        scope.openVerifyForm = function (size) {
            var modalInstance = $modal.open({
                animation: true,
                templateUrl: '../templates/VerifyForm.html',
                controller: verifyFormModalController,
                size: 'lg'
            });
        }
        scope.$watch(function () { return scope.selectIntersectionId }, function () {
            if ((markers.length > 0) && (scope.referencePointSelectMode == "list") && (scope.selectIntersectionId != null)) {
                var referencePointIndex = getMarkerIndexById(scope.selectIntersectionId);
                new google.maps.event.trigger(markers[referencePointIndex], 'click');
            }
        });
        scope.$watch(function () { return scope.referencePoints; }, function (newValue, oldValue) {
            for (var count = 0; count < markers.length; count++) {
                markers[count].setMap(null);
            }
            markers = [];
            bounds = new google.maps.LatLngBounds();
            initMap();
            if(scope.referencePoints.length>0) {
                angular.forEach(scope.referencePoints, function (value, key) {
                    var position = new google.maps.LatLng(value.latitude, value.longitude);
                    setMarker(position, value.title, value.id);
                });
                map.fitBounds(bounds);
            } 
        }, true);

        //Changing watch to broadcast listener
        $rootScope.$on('pointNotFound.Changed', function (event,args) {
            if (args.state == true) setMapClickEvent();
            else clearMapClickListener();
            scope.pointNotFound = args.state;
        });
        $rootScope.$on('routeNotFound.Changed', function (event, args) {
            if (args.state == true) setMapClickEvent();
            else clearMapClickListener();
            scope.routeNotFound = args.state;
        });
        scope.$watch(function () { return scope.clearCrashMarker }, function (newValue, oldValue) {
            if (newValue == true) {
                clearCrashMarker();
            }
        });
        // receive broadcasted events
        scope.$on('clearCrashMarkerEvent', function (event, args) {
            scope.clearCrashMarker = args.state;
        });
    }
    return {
        restrict: 'EA',
        template: "<div id='mappe' style='height:693px;width:100%'></div>",//'../templates/gomap.html', 
        link: link,
        scope: false,
        replace:false
    }
});
  • 0
    Вы можете прочитать этот stackoverflow.com/questions/14049480/… чтобы понять, как работает вложенная область
  • 1
    Есть ли у gmap-locator собственная область выделения? Если нет, он использует область действия домашнего контроллера и, таким образом, переопределяет функцию, которая уже была определена домашним контроллером. Разместите свой код директивы.
Показать ещё 3 комментария
Теги:
angular-ui-router
angularjs-scope
angularjs-directive

1 ответ

0
Лучший ответ

Директива gmap-locator не имеет собственной возможности. Таким образом, он фактически переопределяет функцию в той же области, что и область домашнего контроллера.

Директива должна создавать свою собственную область видимости с использованием scope: true или scope: {} если вы хотите, чтобы она была изолирована.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню