$ scope。$ watch inside指令未被调用

时间:2015-12-08 22:21:06

标签: javascript angularjs google-maps angularjs-directive angularjs-scope

我真的不知道这个代码出了什么问题,我创建了一个指令来监视MapController的模型“List”更改,并且应该在指令中触发一些代码,但不幸的是$ watch没有被触发。

=> Fiddle< =

代码:

 var APP = angular.module('appSite',[])
.controller('MapController', function($scope) {
$scope.List = [];


$scope.Stuff = function(){
    var oTarget = { Pos: { Lat: 10, Lng: 10 }, Des: 'Imovel 1', Id: 1 }
    $scope.List.push(oTarget);
}
})
.service('LoadGMapAPI',function($q, $window){

    this.loadScript = function() {
        var s = document.createElement('script')
        s.src = '//maps.googleapis.com/maps/api/js?language=en&callback=initMap'
        document.body.appendChild(s)
    }

    var deferred = $q.defer();

    $window.initMap = function () {
        deferred.resolve();
    }

    this.loadAPI = deferred.promise;
}).directive('hitmap', ['LoadGMapAPI', function(LoadGMapAPI) {  

var link = function( $scope, elem, attrs ) 
{
    //----  HERE IS THE PROBLEM ----
    $scope.$watch('List', function(newValue, oldValue) {
            if ($scope.List != undefined) { alert('Yeah !') } 
    },true);

    if ( angular.isDefined($scope.lat) && angular.isDefined($scope.lng) ) 
    {

        $scope.initialize = function() 
        {                                        
            $scope.location = new google.maps.LatLng($scope.lat, $scope.lng);

            $scope.mapOptions = {
                zoom: 3,
                center: $scope.location
            };

            $scope.map = new google.maps.Map(document.getElementById($scope.MapID), $scope.mapOptions);

        }

          LoadGMapAPI.loadAPI.then(function () {
            $scope.initialize();
          });

          LoadGMapAPI.loadScript();
        }
    }

    return { 
        link: link,
        restrict: 'E',
        scope: {
            lat: '@',
            lng: '@',
            MapID: '@id'
        }
    }
}]);

HTML:

 <body ng-app="appSite">
      <div ng-controller="MapController">
          <input type="button" value="Click me  to say Yeah " ng-click="Stuff()" />
          <hitmap id="mapSearch" lat="25" lng="-80.4"  />
      </div>
 </body>

2 个答案:

答案 0 :(得分:2)

您正在尝试在指令范围内查看属性,但您已指定指令范围应为isolate scope

试试这个:

return { 
    link: link,
    restrict: 'E',
    scope: {
        lat: '@',
        lng: '@',
        MapID: '@id',
        List: '=@list'
    }
}
<hitmap id="mapSearch" lat="25" lng="-80.4" list="List"  />

这些更改在指令的隔离范围上配置一个新的双向绑定变量。然后将列表从父控制器传递到指令的属性,angular设置控制器变量和指令变量之间的双向绑定。现在,您可以在指令的链接函数中成功$watch 'List'

http://codetunnel.io/isolate-scopes-explained/

答案 1 :(得分:0)

是的,我很惊讶,我对Angular的整个问题主要是“AngularJS Expression Case敏感编译问题”。

首先,AngularJS中的表达式评估对于变量是 caseSensitive ,所以......我的第一个问题是以大写方式使用单个字段“List”而不是“list”。

  1. 已更改:$scope.List = [];$scope.list = [];

  2. 正如Chev在回答中指出的那样,我也错过了scope中的双向约束。将其添加为双向('='

    2.1可选 - 将指令隔离范围字段“list”重命名为“listinherit”(不需要重命名,我只是为了进一步澄清......):

  3. 添加了与控制器范围绑定的属性

    <hitmap id="mapSearch" lat="25" lng="-80.4" listinherit="list" />
    
  4. 更改了监视表达式以观看 IsolatedScope 字段"listinherit"和... 瞧!它按预期工作了!

     $scope.$watch('listinherit', function(newValue, oldValue) {
         if ($scope.listinherit != undefined) { alert('Yeah !') } 
     },true);
    
  5. 检查解决方案:Fiddle