0

我無法理解嵌套場景中範圍的層次結構。AngularJS和範圍層次

我正在使用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()'被調用,但令我驚訝的是'gmap-locator的控制器中的funcXYZ()'被調用,直到我發表評論爲止(然後它傳播到家庭控制器的功能)。

它不屬於傳播的正確層次,至少有我的理解..任何想法?

我使用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

你可以閱讀這個http://stackoverflow.com/questions/14049480/what-are-the-nuances-of-scope-prototypal-prototypical-inheritance-in-angularjs瞭解嵌套示波器的工作原理 –

+1

gmap-定位器有其自己的隔離範圍?如果沒有,它使用家庭控制器範圍,並因此重新定義家庭控制器已經定義的功能。發佈您的指令代碼。 –

+0

我已經添加了指令代碼。它沒有一個孤立的範圍 – Hasteq

回答

0

gmap-locator指令沒有自己的作用域。所以它實際上重新定義了與家庭控制器範圍相同範圍內的功能。

該指令應該創建自己的作用域,使用scope: truescope: {}如果你希望它是孤立的。