无法在AngularJS中的路径控制器之间停止事件传播

时间:2014-11-16 07:43:18

标签: javascript angularjs events angularjs-routing

我正在使用Angular Route来构建SPA,其路由由公共父控制器封装。在父控制器内部,有一个按钮,它将发出一个假设被所有子/路由控制器捕获的事件,每个控制器决定如何处理它。

我希望此事件由父控制器发出一次,并由每个子/路由控制器接收一次。我在这里有一个Plunker http://plnkr.co/edit/9twoe6WO3eLQzVDatrC0?p=preview,表示尝试失败。

该代码段的问题在于,每次路由导航时,同一个子/路由控制器都会再次接收该事件。

PS:来自Plunker的代码

HTML

  <body ng-controller="MainCtrl">
    <ng-view></ng-view>
    <button ng-click="navigate()">Propagate</button>
    <script type="text/ng-template" id="viewIndexCtrl.html">
      <p>this is index page</p>
    </script>
    <script type="text/ng-template" id="viewPackageCtrl.html">
      <p>this is package page</p>
    </script>
  </body>

JS

var app = angular.module('plunker', ['ngRoute']);
app.config(['$routeProvider',
  function($routeProvider) {
    $routeProvider.when('/index', {
      controller: 'viewIndexCtrl',
      templateUrl: 'viewIndexCtrl.html'
    }).when('/package', {
      controller: 'viewPackageCtrl',
      templateUrl: 'viewPackageCtrl.html'
    }).otherwise({
      redirectTo: '/index'
    });
  }
]);

app.controller('MainCtrl', function($scope, $location, $rootScope) {
  $scope.navigate = function() {
    var route = location.href.indexOf('index') > -1 ? 'package' : 'index';

    $location.path('/' + route);
    $rootScope.$emit('navigate');
  };
});

app.controller('viewIndexCtrl', function($scope, $rootScope) {
  $rootScope.$on('navigate', function(e) {
    e.preventDefault();
    e.stopPropagation();

    console.log('event reached index');
  });
});
app.controller('viewPackageCtrl', function($scope, $rootScope) {
  $rootScope.$on('navigate', function(e) {
    e.preventDefault();
    e.stopPropagation();

    console.log('event reached package');
  });
});

1 个答案:

答案 0 :(得分:0)

  • 您需要的是使用$broadcast而不是$emit
  • 你把监听器放在$rootScope上,每当一个控制器被销毁时,它的范围也会被破坏,因此所有它的范围监听器都会被自动删除,但当你把监听器放在{{1}上时你需要手动删除它们。您的代码中发生的事情是,您在每次路由更改时都会将一个侦听器附加到$rootScope,而不会删除以前的侦听器。如果您使用控制器的本地$rootscope,则无需执行任何操作。

这可能就是您所需要的(plunker):

$scope