问题
I am working on a sign-in page using AngularJS and Firebase. So far, most of my code has been working fine, until I tried to add notifications. It seems that the won't display when ng-show says that they should. It takes two clicks to work, which should never be the case. As of now, I have the following button.
<button ng-click="cna()" type="button" class="btn btn-success ban block" style="width:50%">Create New Account</button>
The cna() function is the Create New Account function. This looks like:
create($scope.email, $scope.password);
The create() method looks like:
function create(email, password) {
firebase.auth().createUserWithEmailAndPassword(email,password).catch(function(error){
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode+":"+errorMessage);
$scope.failure = true;
$scope.success = false;
});
firebase.auth().onAuthStateChanged(function(user){
if(user){
$scope.success = true;
$scope.failure = false;
}else{}
});
}
Lastly, I have two notifications that are supposed to show up when $scope.success or $scope.failure are set to true. However, this only works on the second click which, as it should, fails. So, my problem here is that my Account is being created, but my GUI is not being notified until the second click. There shouldn't be a second click at all for it to work.
Finally, my notification code looks like:
<div class="alert alert-success" ng-show="success"><strong>Success!</strong> You made an account!</div>
<div class="alert alert-danger" ng-show="failure"><strong>Sorry!</strong> This user already exists...</div>
I have looked all of the web, and so far all I have found is something called AngularFire that may be a good alternative, but I'm not sure. If anyone can help me with my problem, I would really appreciate it!
回答1:
If you update the scope in a callback function, AngularJS is not aware of that update. And that means it doesn't update the views. So while the data is updated, the views are not. That's also why when you click again (or in some other way force a refresh of the views), the data shows up.
The solution is to explicitly tell AngularJS that it needs to refresh the views by calling $timeout()
or $apply()
.
function create(email, password) {
firebase.auth().createUserWithEmailAndPassword(email,password).catch(function(error){ $timeout(function() {
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode+":"+errorMessage);
$scope.failure = true;
$scope.success = false;
})});
firebase.auth().onAuthStateChanged(function(user){
if(user){
$timeout(function() {
$scope.success = true;
$scope.failure = false;
});
}else{}
});
}
A lot of these type of cases are handled automatically if you use the standard binding library: AngularFire.
回答2:
if you do not see any message after your first click (do you?), try to add success function to your promise:
function create(email, password) {
firebase.auth().createUserWithEmailAndPassword(email,password).then(function () {
// you may want to add some condition here
$scope.success = true;
}, function(error){
var errorCode = error.code;
var errorMessage = error.message;
console.log(errorCode+":"+errorMessage);
$scope.failure = true;
});
firebase.auth().onAuthStateChanged(function(user){
if(user){
$scope.success = true;
$scope.failure = false;
}else{}
});
}
来源:https://stackoverflow.com/questions/39604921/why-does-my-angulars-ng-show-call-only-get-updated-on-the-second-click-using-fi