Angularjs - $rootScope in directive link function

后端 未结 6 585
庸人自扰
庸人自扰 2021-01-30 10:57

I am asking this question because I am not quite clear on how to think of rootscope as a dependency passed to directives

I have a directive that needs to display some in

相关标签:
6条回答
  • 2021-01-30 10:59

    You can do this way:

    {{$root.rsLabels.welcome}}
    
    0 讨论(0)
  • 2021-01-30 11:00

    After laboring away on this same question for quite some time, 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);
                })
            }
        };  
    }]);
    

    Aside from the more philosophical design question of whether or not you should even use $rootScope at all, there is one blatantly wrong thing with my code above that I feel was left out from Mike's solution - the reference to $rootScope. If you're like me and have segregated your directive and controller files you will need to modify 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);
                })
            }
        };  
    }]);
    

    Yet, there is still one more nagging question: can I accomplish the same goal without referencing $rootScope in the directive? Indeed you can. You need to broadcast the change to the $rootScope property effectively letting all child scopes know about the change and watching for 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);
                })
            }
        };  
    }]);
    
    0 讨论(0)
  • 2021-01-30 11:04

    Another way is to create a service and throw that service access the $rootScope and other functions. I did it like this 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 solution. if not, try my solution.

    0 讨论(0)
  • 2021-01-30 11:05

    It's not recommended to use the root scope to set and get properties in your angular application. Try using the $cacheFactory, since that way you can also cache some values over various requests. ($cacheFactory docs)

    0 讨论(0)
  • 2021-01-30 11:09

    From my experiments \ experience, it seems that since all $scopes ultimately inherit from the $rootScope you will be able to access data on it without requesting it as a service, following standard javascript prototypical inheritance rules. If you were to set the scope property in your directive to false or {} you will find that you can no longer access 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

    0 讨论(0)
  • 2021-01-30 11:14

    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;
        });
      };
    }]);
    
    0 讨论(0)
提交回复
热议问题