如何关闭工厂方法中的eventlistener,它正在向控制器返回promise
How to turn off eventlistener in factory method which is returning promise to controllers?
我有一个loginService工厂,用于执行登录、注销和向控制器提供用户数据。因为我需要在每次loginstate更改时更新控制器中的userdata,所以我的工厂方法返回一个更新承诺:
app.controller('TestCtrl', function ($scope, loginService) {
loginService.currentUserData().then(null, null, function(CurrUserData){
$scope.CurrUserData = CurrUserData;
});
});
在loginService中,我正在监听$ firebasesimplellogin:login/logout事件,在它们被触发后,我将userdata对象(由基于UID的函数返回)或null ($ fbsimplellogin:logout事件)传递给$emit。最后,在我的loginService.currentUserData()方法中,我正在监听这个发出的事件并返回deferred.notify(userdata/null)。
第一个问题是,当我改变视图(模板+ctrl+位置),我需要调用$ firebasesimplellogin:login/logout事件交付我的userData到新的控制器。现在,我正在做$locationChangeStart事件,但应该有更好的方法…
最后一个问题:当我改变视图时,有比我预期更多的数据调用。可能每个控制器通过调用loginService.currentUserData()在$rootScope上添加事件侦听器?如下代码:
$rootScope.$on('$firebaseSimpleLogin:login', function (e, authUser) {
findUserByUid(authUser.uid);
});
$rootScope.$on('$firebaseSimpleLogin:logout', function() {
$rootScope.$emit('userLogout', null);
});
$rootScope.$on('$locationChangeStart', function(event, next, current) {
currentUser().then(function(u){
$timeout(function() { // without this same event on viewchange is fired
// by simplelogin, collision (I need to replace this whole block with invoking simpleloginevent)
if (u) {$rootScope.$emit('$firebaseSimpleLogin:login', u);
} else {$rootScope.$emit('$firebaseSimpleLogin:logout', null);};
}, 150);
});
});
function findUserByUid (uid) {
var query = $firebase(usersRef.startAt(uid).endAt(uid));
query.$on('loaded', function () {
var username = query.$getIndex()[0];
setCurrentUser(username);
});
}
function setCurrentUser (username) {
if (username) {$rootScope.$emit('userData', $firebase(usersRef).$child(username));};
}
var currentUserData = function () { // this method is used in CTRLs
var deferred = $q.defer();
var uDl = $rootScope.$on('userData', function(e, FbUserData){deferred.notify(FbUserData); });
var uLl = $rootScope.$on('userLogout', function(){deferred.notify(null); });
return deferred.promise;
};
我最近编写了一个演示AngularFire应用程序,具有类似的功能。我发现处理这个问题的方法就是只担心三点。
-
用户登录
$rootScope.$on('$firebaseSimpleLogin:$login')
-
用户注销时
$rootScope.$on('$firebaseSimpleLogin:$logout')
-
呼叫
$getCurrentUser()
这将能够捕获登录生命周期。由于需要知道当前用户是谁,因此可以依赖于$ firebasesimplellogin方法,而不是尝试$emit自己的事件。
你也可以在$routeProvider中解析每个视图的当前用户。这样,在用户加载完成之前,每个视图都不会被渲染。
下面是plunker项目和示例Factory:http://plnkr.co/edit/M0UJmm?p=preview
// Auth factory that encapsulates $firebaseSimpleLogin methods
// provides easy use of capturing events that were emitted
// on the $rootScope when users login and out
.factory('Auth', function($firebaseSimpleLogin, Fb, $rootScope) {
var simpleLogin = $firebaseSimpleLogin(Fb);
return {
getCurrentUser: function() {
return simpleLogin.$getCurrentUser();
},
login: function(provider, user) {
simpleLogin.$login(provider, {
email: user.email,
password: user.password
});
},
logout: function() {
simpleLogin.$logout();
},
onLogin: function(cb) {
$rootScope.$on('$firebaseSimpleLogin:login',
function(e, user) {
cb(e, user);
});
},
onLogout: function(cb) {
$rootScope.$on('$firebaseSimpleLogin:logout',
function(e, user) {
cb(e, user);
});
}
}
})
- 在指令控制器中使用$attrs时出现问题
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 使用promise和mongoose对文档进行排序
- 从控制器返回后Ajax启动事件激发
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- Ember.js:将Em.$.getJSON转换为promise并将响应绑定到控制器上下文的正确方法
- 如何测试从promise对象获取数据的控制器
- Jasmine Test Access A Promise 在控制器内部
- 如何使promise数据对象在控制器中可用,并将数据从promise传递给新函数
- 如何用Jasmine测试AngularJS控制器在Promise中返回的值
- 在多个控制器中看到的promise分辨率
- 使用AngularJS中的promise管理来自控制器的服务回调
- 如何从控制器调用嵌套在promise中的函数
- 如何在promise的控制器之外使用函数变量
- 如何更新promise中控制器中定义的参数
- 在加载AngularStrap模态控制器之前解析promise
- 如何关闭工厂方法中的eventlistener,它正在向控制器返回promise
- angular1:如何在父控制器中等待promise解析
- 在$promise中使用$broadcast, mocha如何知道事件何时在控制器$scope中触发?
- 我如何访问"this"在angular js控制器中,从promise方法中