创建角度控制器之间的发射器

时间:2015-05-07 04:36:41

标签: angularjs

我正在使用angularfire与yeoman生成器,并在我的帐户控制器中具有工作注销功能:

  $scope.logout = function() { Auth.$unauth(); };

Auth是:

(function() {
'use strict';
angular.module('firebase.auth', ['firebase', 'firebase.ref'])

  .factory('Auth', function($firebaseAuth, Ref) {
    return $firebaseAuth(Ref);
  });
})();

那部分效果很好。我想在导航栏中创建一个注销按钮,但由于它在不同的范围内,我需要在我的导航控制器中创建一个发射器:

$scope.logout = $scope.$emit('loggedOut'); 

在我的帐户控制器中,我会侦听发出的信号。这两种方式都不起作用:

$scope.$on('loggedOut', function() { Auth.$unauth(); });
$scope.$on('loggedOut', $scope.logout );

谁能告诉我我失踪了什么? 谢谢!

编辑 - 我更新了我的代码,但我仍有问题:

angular.module('rutileApp')
  .controller('AccountCtrl', function ($scope, user, Auth, Ref, $firebaseObject, $timeout) {
    $scope.logout = function() { Auth.$unauth(); };

    $scope.$on('loggedOut', function(event, msg) {
      $scope.logout();
    });
});

angular.module('rutileApp')
  .controller('NavCtrl', function ($scope, $rootScope) {
    $scope.sendLogout = function() {
      $rootScope.$broadcast('loggedOut', {msg: 'logging out'});
    }

  });

我无法在AccountCtrl范围内看到广播信号,即使它只是对于console.log,所以这不是登出功能的问题。

4 个答案:

答案 0 :(得分:1)

修改: 我在下面保留了我的原始答案,但这里有一个更新的plunker,它演示了通过广播调用注销功能(但是你必须已经加载了该控制器的实例才能访问它)。我还展示了如何将注销功能放入工厂中,然后可以将其注入控制器并从任何地方进行调用,并且不需要实例化任何特定的控制器。

另外,只看你的代码,我不明白为什么你不能直接调用你的Auth服务 - 只需将Auth注入你的NavCtrl并像在AccountCtrl中那样添加注销功能: $scope.logout = function() {Auth.$unauth();}

同样的事情......当您可以从任何地方访问该工厂时,没有理由调用AccountCtrl方法。

Plunker

厂:

angular.module('rutileApp')
  .factory('accountFactory', function() {
    return {
      logout: function() {
        console.log('called logout from somewhere')
        return 'called logout from somewhere';
      }

    }
  })

你应该$rootScope.broadcast('logout', msg);

正如其他人提到的那样 - $ emit会将子范围向上的事件触发到父范围。 $ broadcast将事件向下触发到子范围。但是对于兄弟范围,这些都不会起作用。每个范围都是$ rootScope的子代,我们可以通过将它注入我们的控制器从任何地方访问$ rootScope。因此,您希望将事件从$ rootScope发送到子范围。

Plunker

app.controller('MainCtrl', function($scope) {
  $scope.$on('logout', function(event, msg) {
    $scope.msg = msg.msg
    console.log(msg.msg);
  })
});
app.controller('OtherCtrl', function($scope, $rootScope) {
  $scope.sendLogout = function() {
    $rootScope.$broadcast('logout', {msg: 'logging out now!'});
  }
});

答案 1 :(得分:0)

如果导航控制器和帐户控制器没有父子$scope关系(如果实例化控制器的标签没有嵌套),{{1}永远不会工作。

在Angular中,可以使用$scope.$emit('event')(将事件调度到发射器的父作用域)和$emit(将事件调度到发射器的子作用域)发出事件。 )。

解决您的问题的方法是使用$broadcast将事件分派给应用程序的所有范围。不优雅,但它有效!

答案 2 :(得分:0)

很可能这是一个范围层次结构问题,因为没有调用事件处理程序。

在Angular $ emit中,向上发送事件并向下向范围层次结构广播。

导航控制器范围必须是t1的帐户控制器的子范围才能工作。

更好的选择是使用每个控制器范围都会收到的$emit

答案 3 :(得分:0)

$仅向父作用域发出气泡,因此除非您的帐户控制器是导航控制器的父级,否则它不会起作用。如果是孩子,你可以使用$ broadcast。如果没有关系,则必须在$ rootScope上。更长的回答:Working with $scope.$emit and $scope.$on