我有一个 loginService 工厂,用于执行登录、注销并向控制器提供用户数据。因为每次登录状态更改时我都需要更新控制器中的用户数据,所以我的工厂方法返回了一个更新承诺:
app.controller('TestCtrl', function ($scope, loginService) {
loginService.currentUserData().then(null, null, function(CurrUserData){
$scope.CurrUserData = CurrUserData;
});
});
在 loginService 中,我正在监听 $firebaseSimpleLogin:login/logout 事件,在它们被触发后,我将 userdata 对象(由基于 UID 的函数返回)或 null($fbSimpleLogin:logout 事件)传递给 $emit。最后,在我的 loginService.currentUserData() 方法中,我正在监听这个发出的事件并返回 deferred.notify(userdata/null)。
第一个问题是,当我更改视图(模板+ctrl+位置)时,我需要调用 $firebaseSimpleLogin: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;
};