在不注入$rootScope的情况下对指令中的角度事件做出反应

Reacting on angular events in a directive without injecting $rootScope

本文关键字:事件 指令 注入 rootScope 情况下      更新时间:2023-09-26

我想知道您是否有一个指令代码的示例,该代码对$routeChangeError等角度事件做出反应,而无需向其注入$rootScope(在链接函数中使用$on)。在我看来,它打破了 MV* 模式并"产生"气味代码(提供了在指令中操纵根范围的可能性)。提前谢谢。

No. 没有任何方法可以在没有某种访问权限的情况下收听 Angular 事件 $scope . 这是他们拥有$rootScope服务的主要原因之一,因此您可以在服务或其他模块中访问$scope

但是,在指令中,不需要注入$rootScope因为链接函数的指令中已经有一个隔离作用域。

例如:

.directive('myDirective', function(){
    return {
        restrict: 'A',
        link: function(scope, elem, attrs){
            scope.$on('some-event', function(e){
                // respond to event here
            });
        }
    };
});

scope变量是一个"隔离"作用域,因此它不会以任何方式影响其父作用域。 但是,如果您尝试将事件发送到某个姐妹级模块,这确实会产生一些奇怪的副作用,因为 Angular 事件仅通过范围层次结构向上或向下$broadcast $emit。 如果您不是,那么上面的示例应该可以完美运行。 如果是,那么以下示例是一种方法:

.directive('myDirective', function($rootScope){
    var isolateScope = $rootScope.new();  // creates a new isolate copy of $rootScope
    return {
        restrict: 'A',
        link: function(scope, elem, attrs){
            isolateScope.$on('some-event', function(e){
                // respond to event here
            });
        }
    };
});

这将创建$rootScope的类似隔离副本,以便您对其所做的任何更改都不会影响其他模块或服务。 这将防止您所说的"smell-code"出现任何问题。

如果您只侦听事件,则不必使用 $rootScope ; 例如 $scope.$on("$routeChangeError")指令的范围,从控制器或链接功能。

你看到"$routeChangeError"是从$rootScope广播的,所以所有的孩子都会收到它。

$on方法是在内部Scope.prototype上定义的,并且由于Angular中的每个作用域都是从构造函数创建的Scope这意味着每个作用域本身都有一个可用的$on方法。无需注入$rootScope,只需直接在指令链接函数的作用域调用$on方法即可:

app.directive('myDirective', function(){
  return function(scope, element, attrs){
    scope.$on('$routeChangeError', function(){
      // ...
    });
  }
});