2014-05-11 14 views
74

Với phạm vi cô lập, mẫu của chỉ thị dường như không thể truy cập bộ điều khiển ('Ctrl') biến $ rootScope, tuy nhiên, không xuất hiện trong bộ điều khiển của chỉ thị. Tôi hiểu tại sao bộ điều khiển ('Ctrl') biến $ scope không hiển thị trong phạm vi cô lập.

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

Biến được truy cập không có phạm vi cô lập - như có thể thấy bằng cách bình luận dòng phạm vi cô lập:

 // scope: {}, 
+0

Có bạn đã thử tiêm $ rootScope vào chỉ thị ... 'chỉ thị ('myTemplate', hàm ($ rootSc ope) {...}) '? –

+0

@MarcKline Chỉ cần thử điều đó và không có may mắn. –

+0

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

Trả lời

151

Bạn có thể thử cách này bằng cách sử dụng $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

Tôi đánh dấu đây là câu trả lời vì nó 'giải quyết' những gì tôi muốn đạt được (tôi không biết '$ ​​root' hoặc nó có thể được sử dụng như thế này). ** Tuy nhiên **, tôi cho rằng câu trả lời của Mark Kline nói chung là giải pháp tốt nhất. –

+5

tuyệt vời! khá hữu ích khi biết rằng $ rootScope thay đổi thành $ root thành các khung nhìn, cảm ơn rất nhiều! –

+0

Điều này là hoàn hảo vì những gì tôi cần làm là truy cập vào một chức năng được xác định trong rootScope –

20

1) Do cô lập phạm vi $scope trong bộ điều khiển Ctrl và trong bộ điều khiển chỉ thị không tham chiếu đến cùng phạm vi - giả sử chúng tôi có scope1 trong Ctrl và scope2 theo chỉ thị.

2) Do phạm vi cô lập scope2không prototypicallly kế thừa từ $rootScope; vì vậy nếu bạn xác định $rootScope.blah thì không có cơ hội nào bạn có thể nhìn thấy nó trong scope2.

3) Những gì bạn có thể truy cập trong mẫu chỉ thị của bạn là scope2

Nếu tôi tóm tắt, đây là sơ đồ thừa kế

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


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

Rất hữu ích nhưng cách giải quyết của nidhishkrishnan không hoạt động nếu bằng cách nào đó sử dụng các giá trị rootScope là cần thiết. Một hack tốt đẹp nó được. –

+0

Vâng, những gì bạn nói là logic để trả lời lý do tại sao tôi không thể sử dụng biến $ rootScope trong html (không có $ root.), Nhưng khi tôi sử dụng plug-in Batarang để xem $ scopes, tôi có thể thấy rõ ràng $ rootScope là phạm vi $ parent của tất cả những người khác (bao gồm cả phạm vi cô lập trong các chỉ thị). Ngoài ra, định nghĩa từ tài liệu chính thức góc nói: "Mỗi ứng dụng đều có một phạm vi gốc duy nhất. Tất cả các phạm vi khác là phạm vi hậu duệ của phạm vi gốc" (https://docs.angularjs.org/api/ng/service/$ rootScope) – IsraGab

31

Nói chung, bạn nên tránh sử dụng $rootScope để lưu trữ các giá trị bạn cần chia sẻ giữa các bộ điều khiển và chỉ thị. Nó giống như sử dụng globals trong JS. Sử dụng dịch vụ thay thế:

Giá trị không đổi (hoặc giá trị ...sử dụng là tương tự):

.constant('blah', 'blah') 

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

Một nhà máy (hoặc dịch vụ hoặc nhà cung cấp):

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

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

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

    return blah; 
}) 

Đây là một fork of your Fiddle chứng minh làm thế nào bạn có thể sử dụng một trong hai

+3

+1 Cảm ơn rất nhiều về điều này và đã chỉ cho tôi theo hướng ** đúng ** cho những gì tôi đang cố gắng đạt được. Tôi nghĩ rằng NidhishKrishnan nên được chấp nhận là 'câu trả lời' cho lý do được nêu trong bình luận của tôi. –

+1

+1 cho trường hợp sử dụng các hằng số vì chúng hiếm khi được sử dụng. Ngoài ra lưu ý về việc không sử dụng $ rootScope là một mẹo chuyên nghiệp. –

Các vấn đề liên quan