Reputation: 10408
I have a bunch of properties on an object that are determined dynamically:
$scope.buttons.isVisible = {
buttonOne: $scope.timeBetween > -(60 * 60) && $scope.timeBetween < 30,
buttonTwo: $scope.timeBetween > -(60 * 15) && $scope.timeBetween < -(60 * 8),
buttonThree: $scope.timeBetween > -(60 * 15)
}
I use these variables to determine the visibility of some buttons on a page:
<button class="canned-response" ng-if="buttons.isVisible.buttonOne">Button Text</button>
The variable $scope.timeBetween
is updated once per second inside of a function which is a callback of a countdown directive:
$scope.setTimeBetween = function(relativeSecondsBetween) {
$scope.timeBetween = relativeSecondsBetween;
};
An example of the usage of the directive:
<countdown countdown-to="someVar" callback="setTimeBetween"></countdown>
The issue is that changes to $scope.timeBetween
are being made, but those changes are not propagating through to my button visibility booleans.
If I try and call $scope.$apply()
at the end of the setTimeBetween
function, I get a "digest already in progress" error. Wrapping the variable assignment in a $timeout
does nothing either.
What's the best solution to this?
Upvotes: 0
Views: 65
Reputation: 3987
You need to watch $scope.timeBetween for changes, then update your button visibility object.
$scope.$watch(function() {
return $scope.timeBetween;
}, function(newValue, oldValue) {
$scope.buttons.isVisible = {
buttonOne: newValue > -(60 * 60) && newValue < 30,
buttonTwo: newValue > -(60 * 15) && newValue < -(60 * 8),
buttonThree: newValue > -(60 * 15)
};
});
Also, as a best practice, you should set up this watch in your directive's link function, not the controller.
Upvotes: 1
Reputation: 2800
The button visibility booleans are evaluated only once.
One solution is to define them as functions:
buttonOne: function () {
return $scope.timeBetween...;
}
And then call the functions in ng-if:
ng-if="buttons.isVisible.buttonOne()"
Upvotes: 1