我正在使用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,所以这不是登出功能的问题。
答案 0 :(得分:1)
修改强>: 我在下面保留了我的原始答案,但这里有一个更新的plunker,它演示了通过广播调用注销功能(但是你必须已经加载了该控制器的实例才能访问它)。我还展示了如何将注销功能放入工厂中,然后可以将其注入控制器并从任何地方进行调用,并且不需要实例化任何特定的控制器。
另外,只看你的代码,我不明白为什么你不能直接调用你的Auth服务 - 只需将Auth
注入你的NavCtrl并像在AccountCtrl中那样添加注销功能:
$scope.logout = function() {Auth.$unauth();}
同样的事情......当您可以从任何地方访问该工厂时,没有理由调用AccountCtrl方法。
厂:
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发送到子范围。
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