0

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.

2 Answers 2

1
$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.

Sign up to request clarification or add additional context in comments.

Comments

1

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.