48

我问这个问题是因为我不太清楚如何将 rootscope 视为传递给指令的依赖项

我有一个指令需要显示来自 $rootScope 的一些信息...

我以为我需要将 $rootScope 传递给指令,但是当我编写这样的指令时,它似乎可以工作。

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

我什么时候需要这样做?

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

如果我需要在指令的链接功能中使用 rootScope,我可以以及如何使用它- 还是应该在指令的控制器中使用它?

.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>'
}
})

我的 rootScope 数据是在运行函数中定义的

 .run(function ($rootScope) {

  $rootScope.rsLabels = { 
      welcome: 'Welcome'
  };

  $rootScope.rsUser = { 
     firstName: 'Joe'
  };
});

谢谢!

4

6 回答 6

70

你可以这样做:

{{$root.rsLabels.welcome}}
于 2014-05-28T08:32:22.857 回答
53

根据我的实验\经验,似乎由于所有 $scopes 最终都从 $rootScope 继承,您将能够访问其上的数据,而无需将其作为服务请求,遵循标准的 javascript 原型继承规则。如果您将指令中的范围属性设置为 false 或 {},您会发现您无法再访问它。

.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>'
    };
});

示例:http: //jsbin.com/bequy/1/edit

于 2014-02-12T19:02:44.957 回答
7

不建议使用根范围来设置和获取 Angular 应用程序中的属性。尝试使用 $cacheFactory,因为这样您还可以在各种请求中缓存一些值。($cacheFactory 文档

于 2014-02-12T18:48:09.607 回答
7

有时我必须使用 $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;
    });
  };
}]);
于 2016-09-05T16:14:11.387 回答
4

在同一个问题上苦苦思索了很长一段时间后,我认为值得注意的是在第一篇文章中被忽略的一些内容。这是我的原始代码:

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

除了你是否应该使用 $rootScope 的更具哲学性的设计问题之外,我觉得上面的代码中有一个明显错误的地方,我觉得 Mike 的解决方案忽略了 - 对 $rootScope 的引用。如果你和我一样,并且已经分离了你的指令和控制器文件,你将需要修改你的代码,如下所示:

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

然而,还有一个更烦人的问题:我可以在引用指令中的 $rootScope 的情况下实现相同的目标吗?确实可以。您需要有效地将更改广播到 $rootScope 属性,让所有子范围都知道更改并在指令中监视此更改。

控制器:

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

指示:

app.directive('countrymapalt', [function() 
{
    return {
        link: function(scope, element, attrs) {
            scope.$on("countryMapChanged", function(event, map) 
            {
                setTimeout( function() 
                { 
                    //function body here
                }, 100);
            })
        }
    };  
}]);
于 2015-08-07T01:28:48.170 回答
1

另一种方法是创建一个服务并让该服务访问 $rootScope 和其他功能。我这样做是因为我的环境......

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})
   }
});

如果可以,最好的方法是迈克解决方案。如果没有,请尝试我的解决方案。

于 2016-03-21T09:28:12.720 回答