2014-05-11 18 views
74

使用隔離範圍時,指令的模板似乎無法訪問控制器('Ctrl')$ rootScope變量,但該變量出現在指令的控制器中。我明白爲什麼控制器('Ctrl')$ scope變量在隔離範圍中不可見。

HTML:

<div ng-app="app"> 
    <div ng-controller="Ctrl"> 
     <my-template></my-template> 
    </div> 

    <script type="text/ng-template" id="my-template.html"> 
     <label ng-click="test(blah)">Click</label> 
    </script> 
</div> 

JavaScript的:

angular.module('app', []) 
    .controller('Ctrl', function Ctrl1($scope, $rootScope) { 
     $rootScope.blah = 'Hello'; 
     $scope.yah = 'World' 
    }) 
    .directive('myTemplate', function() { 
     return { 
      restrict: 'E', 
      templateUrl: 'my-template.html', 
      scope: {}, 
      controller: ["$scope", "$rootScope", function($scope, $rootScope) { 
       console.log($rootScope.blah); 
       console.log($scope.yah);, 

       $scope.test = function(arg) { 
        console.log(arg); 
       } 
      }] 
     }; 
    }); 

JSFiddle

該變量沒有分離範圍訪問 - 如可以通過註釋分離範圍線可以看出:

 // scope: {}, 
+0

有您嘗試將$ rootScope注入指令...'指令('myTemplate',function($ rootSc ope){...})'? –

+0

@MarcKline剛剛嘗試過,沒有運氣。 –

+0

http://stackoverflow.com/questions/13895124/unable-to-access-rootscope-var-in-directive-scope –

回答

151

你可以試試這個出路使用$root.blah

Working Code

HTML

<label ng-click="test($root.blah)">Click</label> 

的JavaScript

angular.module('app', []) 
    .controller('Ctrl', function Ctrl1($scope, $rootScope) { 
     $rootScope.blah = 'Hello'; 
     $scope.yah = 'World' 
    }) 
    .directive('myTemplate', function() { 
     return { 
      restrict: 'E', 
      templateUrl: 'my-template.html', 
      scope: {}, 
      controller: ["$scope", "$rootScope", function($scope, $rootScope) { 
       console.log($rootScope.blah); 
       console.log($scope.yah); 

       $scope.test = function(arg) { 
        console.log(arg); 
       } 
      }] 
     }; 
    }); 
+6

我將此標記爲答案,因爲它解決了我想要實現的目標(我不知道「$ root」或者它可以像這樣使用)。 **然而**,我會建議馬克克萊恩的答案通常是最好的解決方案。 –

+5

太棒了!它非常有用,知道$ rootScope變成$ root到視圖中,非常感謝! –

+0

這是完美的,因爲我需要做的是訪問rootScope中定義的函數 –

20

1)由於中隔離範圍$scope在您的控制器Ctrl和指令控制器中不涉及相同的範圍 - 讓我們說我們有範圍1在Ctrl和範圍2 in指令。

2)由於分離範圍的scope2 prototypicallly從$rootScope繼承;所以如果你定義$rootScope.blah,你就不可能在scope2中看到它。

3)你可以在你的指令模板訪問是scope2

如果我總結一句話,這裏是繼承模式

_______|______ 
    |   | 
    V   V 
$rootScope  scope2 
    | 
    V 
    scope1 


$rootScope.blah 
> "Hello" 
scope1.blah 
> "Hello" 
scope2.blah 
> undefined 
+1

非常有幫助,但nidhishkrishnan的解決方法確實有效,如果以某種方式使用rootScope值是必要的。它是一個很好的黑客。 –

+0

那麼,你說的是爲了回答爲什麼我不能在html中使用$ rootScope變量(沒有$ root。),但是當我使用Batarang插件查看$ scopes時,我可以清楚地看到$ rootScope是所有其他父級$的範圍(包括指令中的隔離範圍)。另外,角度官方文檔中的定義表示:「每個應用程序都有一個單獨的根作用域,其他所有作用域都是根作用域的後代作用域」 (https://docs.angularjs.org/api/ng/service/$ rootScope) – IsraGab

31

一般來說,你應該避免使用$rootScope存儲值你需要在控制器和指令之間共享。這就像在JS中使用全局變量。改爲使用服務:

常數(或值...使用類似):

.constant('blah', 'blah') 

https://docs.angularjs.org/api/ng/type/angular.Module

出廠(或服務提供方):

.factory('BlahFactory', function() { 
    var blah = { 
     value: 'blah' 
    }; 

    blah.setValue = function(val) { 
     this.value = val; 
    }; 

    blah.getValue = function() { 
     return this.value; 
    }; 

    return blah; 
}) 

這裏是一個fork of your Fiddle演示如何使用兩種

+3

+1非常感謝,並指出我正在嘗試實現的**正確**方向。我認爲NidhishKrishnan's應該被接受爲我評論中所述理由的「答案」。 –

+1

+1用於常量的用例,因爲它們很少被使用。另外關於不使用$ rootScope的注意事項是專業技巧。 –

相關問題