2016-01-15 76 views
0

我有下面的代碼

提琴手Link

HTML中的$範圍:

<div ng-app ng-controller="ParentCtrl" ng-init="cities='North America'"> 
     <div ng-controller="ChildCtrl as vm"> 
      {{$parent.cities}} 
      <div> 
      <button ng-click="check()">Check the value</button> 
      </div> 
     </div> 
</div> 

Javascript:

function ParentCtrl($scope, $rootScope) {   
     $rootScope.$watch('changecity', function() {  
      $scope.cities = "South America"; 
      console.log("changed the city");        
     }); 

     $scope.cities = "North America"; 
    } 

    function ChildCtrl($scope, $rootScope) {        
     $scope.check = function(){ 
      console.log("$parent value:"+$scope.$parent.cities + "\n$scope value:"+$scope.cities)   
     }; 
    } 

我有ng-init = "cities='North America'"$scope.cities = "North America";ParentCtrl

但輸出的視圖更新爲南美洲這很奇怪。有人可以解釋在上述代碼塊中發生的執行的全部基礎。

  1. $watch最初執行回調嗎?
  2. 作用域覆蓋的優先級是什麼?即:監視回調中的作用域覆蓋之前設置的值?
+0

不要使用'NG-init'用於這一目的。在控制器中聲明變量 – charlietfl

回答

2

$watch當變量爲undefined時開始觀察。 $ watch將在初始化時觸發,因爲它將undefined視爲範圍變量中的新狀態更改。除此之外,範圍變量$scope.cities = 'North America'的設置被視爲變量的變化。此更改觸發$watch,而這又改變了$scope.cities='South America'

爲了解決這個問題只是檢查舊值不undefined

$rootScope.$watch('changecity', function(newvalue, oldvalue) {  
     // This will only change the cities if the original value was falsy 
     if(oldvalue) { 
     $scope.cities = "South America"; 
     console.log("changed the city");        
     } 
    }); 

更多信息參見:http://jsfiddle.net/7wr6ow57/4/

+0

好了,現在我已經刪除了將範圍設置爲**北美**的所有初始分配。按照這個更新的提琴手http://jsfiddle.net/7wr6ow57/2/。那麼現在觸發'$ watch'將其設置爲**南美**?我仍然可以看到相同的輸出。 – Nirus

+0

$ watch在初始化時也會將'undefined'看作一個新狀態。所以在這種情況下它總是會觸發。我會更新我的答案;) – Erwin

+0

投票部分指出解決方案+1。 – Nirus