Reputation: 19445
High level
I header view and a main view in my angular application. I want the header to have a "back" button that is show/hidden based on the page I'm on.
What I did
app.js (snippet)
app.factory('globalServices', function() {
return {
showBack : false,
back: function() {
window.history.back();
}
};
});
header.html (snippet)
<a class="button-prev" ng-click="back()" ng-show="showBackButton">
Back
</a>
headerCtrl.js (snippet)
$scope.showBackButton = globalServices.showBack;
$scope.back = function() {
globalServices.back();
};
subPageCtrl.js (snippet)
globalServices.showBack = true;
Problem
The button viability isn't refreshed after the value is changed. I only see the value changed after I move one more page.
Is there a way to fix it?
I'm also open for a different approach.
Edit
Trying to call $scope.$apply();
also failed with error $digest already in progress
because I'm changing this value as part of the constructor of subPageCtrl.
Upvotes: 0
Views: 232
Reputation: 7958
This is because when booleans are passed, they are assigned by value (they are a by value type) so when you are doing $scope.showBackButton = globalServices.showBack;
it is assigning the value of $scope.showBackButton
to the value of globalServices.showBack
so if you change the value of globalServices.showBack
it won't change the value of $scope.showBackButton
.
To fix this you should used an object which is assigned by reference:
app.factory('globalServices', function() {
return {
showButtonDetails: {
showBack : false
},
back: function() {
window.history.back();
}
};
});
<a class="button-prev" ng-click="back()" ng-show="showButtonDetails.showBack">
Back
</a>
$scope.showButtonDetails = globalServices.showButtonDetails;
$scope.back = function() {
globalServices.back();
};
globalServices.showButtonDetails.showBack = true;
Upvotes: 1
Reputation: 11190
$scope.showBackButton = globalServices.showBack;
only set's showBackButton to globalServices.showBack once (during controller initialization). Future changes to globalServices.showBack aren't propagated to the $scope.showBackButton, which is the value that your UI is bound to.
You have two options:
1)
$scope.$watch('globalServices.showBack', function(){
$scope.showBackButton = globalServices.showBack;
}
This option will watch globalServices.showBack for changes, and then set $scope.showBackButton to match on any change.
or
2)
$scope.globalServices = globalServices;
<a class="button-prev" ng-click="globalServices.back()" ng-show="globalServices.showBackButton">
Back
</a>
This option exposes globalServices directly to your UI. This is how I would do it.
Upvotes: 1