Angularjs - $ rootScope in directory link function

I ask this question because I do not quite understand how to think about root crops, as a dependency passed to directives.

I have a directive that should display some information from $ rootScope ...

It seemed to me that I needed to pass the $ rootScope directive to the directive, but when I write such a directive, it seems to work.

.directive("myBar", function () { return { restrict: "E", transclude: true, replace: true, template: '<div>' + '<span ng-transclude></span>' + '{{rsLabels.welcome}} {{rsUser.firstName}}!' + '</div>' } }) 

When do you need to do this?

 .directive("myBar", function ($rootScope) { return { restrict: "E", transclude: true, replace: true, template: '<div>' + '<span ng-transclude></span>' + '{{rsLabels.welcome}} {{rsUser.firstName}}!' + '</div>' } }) 

Can I and HOW to use rootScope if I need it in the directive link function , or should I do it in the directive controller?

 .directive("myBar", function ($rootScope) { return { restrict: "E", transclude: true, replace: true, link: function (scope, element, attrs, rootScope) { rootScope.rsUser = { firstName: 'Joe' }; rootScope.rsUser = { welcome: 'Welcome' }; }, template: '<div>' + '<span ng-transclude></span>' + '{{rsLabels.welcome}} {{rsUser.firstName}}!' + '</div>' } }) 

My rootScope data is defined in the start function

  .run(function ($rootScope) { $rootScope.rsLabels = { welcome: 'Welcome' }; $rootScope.rsUser = { firstName: 'Joe' }; }); 

Thank!

+42
angularjs angularjs-scope angularjs-directive rootscope
Feb 12 '14 at 18:44
source share
6 answers

From my experiments / experience, it seems that since all $ scopes are ultimately inherited from $ rootScope, you can access the data on it without requesting it as a service, following the standard rules for inheriting javascript prototypes. If you must set the scope property in your directive to false or {}, you will find that you can no longer get it.

 .directive("myBar", function($rootScope) { return { restrict: "E", scope: { /* Isolate scope, no $rootScope access anymore */ }, transclude: true, replace: true, template: '<div>' + '<span ng-transclude></span>' + '{{rsLabels.welcome}} {{rsUser.firstName}}!' + '</div>' }; }); 

Example: http://jsbin.com/bequy/1/edit

+46
Feb 12 '14 at 19:02
source share

You can do this:

 {{$root.rsLabels.welcome}} 
+58
May 28 '14 at 8:32
source share

It is not recommended that you use the root area to set and get properties in your angular application. Try using $ cacheFactory, as you can also cache some values ​​for various requests. ( $ cacheFactory docs )

+7
Feb 12 '14 at 18:48
source share

After a short dismissal on the same issue, I thought it was worth noting something that was neglected in the first post. Here is my original code:

 app.directive('countrymap', function() { return { link: function(scope, element, attrs) { scope.$watch("countryMap", function (newCountry, oldCountry) { setTimeout( function() { //function body here }, 100); }) } }; }]); 

Besides the more philosophical question of whether to use $ rootScope at all, there is one clearly erroneous fact with my code above, which, it seems to me, was left without Mike's decision - a link to $ rootScope. If you are like me and separated your directory and control files, you will need to change your code as follows:

 app.directive('countrymap', ['$rootScope', function($rootScope) { return { link: function(scope, element, attrs) { $rootScope.$watch("countryMap", function (newCountry, oldCountry) { setTimeout( function() { //function body here }, 100); }) } }; }]); 

However, there is another sharp question: can I achieve the same goal without referring to the $ rootScope in the directive? Indeed you can. You need to pass this change to the $ rootScope property, effectively resolving the change information to all child regions and observing this change in the directive.

Controller:

 $rootScope.countryMap = 'thiscountry_map'; $rootScope.$broadcast( "countryMapChanged", $rootScope.countryMap ); 

Directive

 app.directive('countrymapalt', [function() { return { link: function(scope, element, attrs) { scope.$on("countryMapChanged", function(event, map) { setTimeout( function() { //function body here }, 100); }) } }; }]); 
+3
Aug 07 '15 at 1:28
source share

Sometimes I have to use $ scope. $ root:

 app.directive('setOrdinal', function() { return { link: function($scope, $element, $attr) { var steps = $scope.$root.steps; $scope.$watch(setOrdinal, function(value) { if (value) { // steps code here } }); } }; }); app.controller('stepController', ['$scope', '$rootScope', 'GetSteps', function ($scope, $rootScope, GetSteps) { var s = $scope; var r = $rootScope; s.initialize = function(id) { GetSteps.get({id: id}, function(resp){ r.steps = resp.steps; }); }; }]); 
+3
Sep 05 '16 at 16:14
source share

Another way is to create a service and drop this service on $ rootScope and other functions. I did it like that because of my environment ...

 app.service('myService', function ($rootScope) { this.removeItem = function (el) { console.log('rootScope: ',$rootScope); return true; } }); app.directive('draggable', function($document,myService) { return function(scope, element, attr) { myService.removeItem({id:1}) } }); 

If you can, the best way is Mike's solution. if not, try my solution.

+1
Mar 21 '16 at 9:28
source share



All Articles