1

I am trying to interact with the rootScope in order to make a modal appear. I have a very basic directive that I am trying to use rootScope paired with an ng-show.

Here is the code for the directive:

.directive('modal', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'A',
        templateUrl: 'view/templates/modal-confirm.tpl.html',
        link: function (scope, element, attrs) {
            console.log(scope);

            element.on('click', function() {
                scope.$root.confirmModal.isVisible = true;
                console.log('open modal');
            });
        }
    }
}])

When I log the scope variable, it is showing me as having $root updated with the isVisible: true however, my modal doesn't appear. If I change the scope.$root.confirmModal.isVisible = true; to $rootScope.confirmModal.isVisible = true; I get the same result, the console.log is working but no modal appearing.

This is the code for the modal template:

<!-- Confirm Modal Template -->
<div ng-if="$root.confirmModal.isVisible" class="overlay">
    <div class="overlay-content extended">
        <span>{{ $root.confirmModal.content }}</span>
        <div class="buttons">
            <button ng-click="$root.confirmModal.isVisible = false;" class="btn btn-default half">Cancel</button>
        </div>
    </div>
</div>

Is it not possible to interact with the $rootScope in a directive?

Updated code using scope instead of $rootScope:

.directive('modal', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'A',
        templateUrl: 'view/templates/modal-confirm.tpl.html',
        link: function (scope, element, attrs) {
            scope.isVisible = false;

            element.on('click', function() {
                scope.isVisible = true;
                console.log(scope);
                console.log('open modal');
            });
        }
    }
}])

<!-- Confirm Modal Template -->
<div ng-if="isVisible" class="overlay">
    <div class="overlay-content extended">
        <span>hello world</span>
    </div>
</div>

Same result however.

2
  • why do you need to do this on rootScope? Commented Nov 12, 2013 at 16:51
  • If I change scope.$root.confirmModal.isVisible to just scope.isVisible and $root.confirmModal.isVisible to isVisible, init with scope.isVisible = false; it does not appear on click. It is being set to isVisible: true if I look at the scope after the on-click function. What am I doing wrong? Commented Nov 12, 2013 at 16:57

1 Answer 1

2

You are not doing something wrong you are just missing one line of code. In this statement :

element.on('click', function() {
  scope.isVisible = true;
  console.log(scope);
  console.log('open modal');
});

you are creating an anonymous function, which is perfectly fine, but angular will not be able to auto magically track changes made to scope variables.What you need to do is to explicitly request for a digest cycle at the end of your function either with wrapping your code within $apply or $timeout function. Like so :

element.on('click', function() {
  scope.$apply(function(){ // or $timeout(function() {
    scope.isVisible = true;
    console.log(scope);
    console.log('open modal');
  });

});

If you want to know more about $apply check this great article. Finally I have assemble a Plunker here with your code for you to be able to test.

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

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.