Reputation: 1278
I have a directive that inherits scope from its parent controller. The directive is a div element that overlays the page for three seconds then disappears unless an up/down arrow button is clicked. The div element acts as kind of a modal. This is the code on my DOM
HTML
<div ng-show="volumeVisibility">
<display-volume-modal></display-volume-modal>
</div>
The default setting is false
. When volumeVisibility === true
, the directive will appear upon a button click. So far, so good. These are my two functions in the controller:
$scope.volumeVisibility = false;
$scope.timer = function(){
console.log("Timer");
$scope.volumeVisibility = false;
};
$scope.displayVolumeModal = function(){
$scope.volumeVisibility = true;
console.log("modal");
};
The timeout works and sets $scope.volumeVisibility === false
. However, the div does not remove itself from the page. Here is the code from the directive (I've removed the irrelevant parts):
return {
restrict: 'E',
scope: false,
link: function(scope, elem, attrs){
scope.$watch('volumeVisibility', function(newVal, oldVal){
if (newVal === true){
window.setTimeout(scope.timer, 3000);
document.addEventListener('keydown', function(e){
//stuff
switch (e.which) {
case 38:
//stuff
break;
case 40:
//stuff
break;
}
});
}
}, true);
},
templateUrl: 'public/templates/displayVolumeModal.html'
}
I've tried putting each function into the directive or the controller. What step can I take to make this directive DIV element disappear after timeout?
Upvotes: 0
Views: 1504
Reputation: 221
If you use ng-show and ng-hide it will simply make the visibility hidden of the particular html element on which it is applied. The element will be there in the DOM, no matter if it's ng-hide or ng-show. This is why the directive is not being called.
If you want to call the directive everytime it appears on the screen, simply use ng-if instead of ng-show.
Upvotes: 0
Reputation: 7269
Nothing happens because no digest cycle was called.
To update sync, you have to run digest cycle. I think, in this case, you can use $timeout service instead of setTimeout.
Benefits of $timeout service:
Upvotes: 1
Reputation: 5420
window.setTimeout(scope.timer, 3000);
does not call angular digest
cycle, so watch
doesn't see the changes.
Use angular's $timeout
service instead like this:
$timeout(scope.timer, 3000);
Internally it does the same as window.setTimeout
, but makes sure, that digest
will be called after.
Read more about angular digest cycle and how angular checks if some variable changed. Especially the Integration with the browser event loop
chapter.
Upvotes: 1