2013-12-10 222 views
1

我是新來AngularJS。AngularJS - 範圍的指令

有人能解釋我爲什麼活動類不在此代碼標籤之間切換:http://jsfiddle.net/eSe2y/1/

angular.module('myApp', []) 
.filter('split', function() { 
    return function (input, string) { 
     var temp = string.split('|'); 
     for (var i in temp) 
      input.push(temp[i]); 
     return input; 
    }; 
}) 
.directive('myTabs', function() { 
    return { 
     restrict: 'E', 
     scope: { tabs: '@' }, 
     template: 
      "<div>" + 
       "<a ng-repeat='e in [] | split:tabs' ng-click='selectedIndex = $index' ng-class='{active:$index==selectedIndex}'>{{e}}</a>" + 
      "</div>", 
     replace: true 
    } 
}); 

如果我移動NG-點擊表達給控制器的方法,代碼按預期工作:http://jsfiddle.net/g36DY/1/

angular.module('myApp', []) 
.filter('split', function() { 
    return function (input, string) { 
     var temp = string.split('|'); 
     for (var i in temp) 
      input.push(temp[i]); 
     return input; 
    }; 
}) 
.directive('myTabs', function() { 
    return { 
     restrict: 'E', 
     scope: { tabs: '@' }, 
     template: 
      "<div>" + 
       "<a ng-repeat='e in [] | split:tabs' ng-click='onSelect($index)' ng-class='{active:$index==selectedIndex}'>{{e}}</a>" + 
      "</div>", 
     replace: true, 
     controller: ['$scope', function ($scope) { 
      $scope.onSelect = function (index) { 
       $scope.selectedIndex = index; 
      } 
     }] 
    } 
}); 

有人可以解釋我的區別嗎?以及如何修改第一個代碼以使其工作,而無需爲控制器創建方法?

在此先感謝。

+0

這是一個非常常見的問題的角度。我們今天剛剛在工作中遇到了它(再次)。希望我的解釋在下面幫助。 –

回答

3

問題

問題的說明與javascript inheritance as it relates to scopes and directives in angular做。基本上,當在子範圍內時,基本類型的所有屬性(int,boolean等)都從父級複製。

在你的情況下,NG-重複指令,會爲每個元素的子範圍,所以該環節中的每一個都有自己的範圍。在第一示例中,selectedIndex只從中繼器內引用,每個中繼器元素引用其自身的selectedIndex的副本。您可以在此使用

在第二個例子調查,您可以定義控制器,這是該轉發器的父範圍selectedIndex對象。由於selectedIndex屬性在傳遞給控制器​​時最初未定義,因此它們將向父級定義一個值。當此定義的值在onSelect方法中設置時,所有中繼器元素都會「查看」此值並進行相應更新。

如何調試

在未來,你可以使用Angular Batarang調查這些類型的問題。

  1. 瀏覽http://jsfiddle.net/eSe2y/1/show
  2. 左鍵單擊其中一個標籤
  3. 右鍵單擊相同的鏈接
  4. 選擇「檢查元素」
  5. 打開調試控制檯,然後輸入$ scope.selectedIndex
  6. 爲另一個選項卡重複上述步驟,並注意值的差異
  7. 現在轉到調試器的元素選項卡,然後單擊div
  8. 輸入$ scope.selectedIndex並注意它是不確定的

在第二小提琴,儘量只觀看各標籤(未$scope.selectedIndex)的$scope。你會看到,selectedIndex未在中繼元素來定義,所以他們默認從他們的父母的價值。

最佳實踐

來避免這個問題是要始終引用的項目,可能會改變對「後點」範圍的典型角的最佳實踐。這利用了JavaScript對象被引用繼承的事實,所以當屬性在一個地方改變時,它會在父子層次結構中的所有作用域上發生變化。我已經發布了一個更新的小提琴手,通過簡單地推動結合到物體上解決了這個問題:

angular.module('myApp', []) 
.filter('split', function() { 
    return function (input, string) { 
     var temp = string.split('|'); 
     for (var i in temp) 
      input.push(temp[i]); 
     return input; 
    }; 
}) 
.directive('myTabs', function() { 
    return { 
     restrict: 'E', 
     scope: { tabs: '@' }, 
     template: 
      "<div>" + 
      "<a ng-repeat='e in [] | split:tabs' ng-click='s.selectedIndex = $index' ng-class='{active:$index==s.selectedIndex}'>{{e}}</a>" + 
      "</div>", 
     replace: true, 
     controller: ['$scope', function ($scope) { 
      $scope.s = {}; 

     }] 
    } 
}); 

http://jsfiddle.net/g36DY/2/