1

Here is my directive

.directive('closeMapMessage', function($log) {
  'use strict';
  return function(scope, element) {
    var clickingCallback = function() {
    angular.element('.map').fadeOut("slow");
    };
    element.bind('click', clickingCallback);
  };
})

How can I change a scope variable in the controller ?

<div class="msg-mobile" ng-show="showInstructionModal">
  <div class="close-map-msg ok-got-it-footer" close-map-message>Ok, got it. </div>
</div>

I basically want to set my showInstructionModalfalse when my close directive is called.

StevieB
  • 6,263
  • 38
  • 108
  • 193
  • 1
    What about `scope.showInstructionModal = false; scope.$apply();` at the end of your directive? – tymeJV Apr 14 '15 at 13:27
  • Why aren't you using angular modals? Or ngClick for that matter? – thomaux Apr 14 '15 at 13:31
  • @Anzeo DOM manipulation should be done using directive, so he used directive which is correct – Pankaj Parkar Apr 14 '15 at 13:51
  • @pankajparkar There's no DOM manipulation here. It's a directive to fade out a modal and close it. That can be tackeled either by using Angular UI's modal service or alternatively could be fixed by adding a ng-click attribute and a ng-class that will toggle the fade out. – thomaux Apr 14 '15 at 14:07
  • @Anzeo I looke ` angular.element('.map')` before applying `fadeOut()` ,thats why i love to use directive – Pankaj Parkar Apr 14 '15 at 14:08
  • @pankajparkar Arguably you could use the directive for the fading, but binding the click handler in the directive as in the example provided by the OP is not Angular-like. It would be better to move that to an ng-click handler. An additional advantage over that solution is that you do not require to manually call `scope.$apply()`, which is tricky in all cases (becasue you can run into the error that a $digest cycle's already running) – thomaux Apr 14 '15 at 14:11
  • @Anzeo It would be bad way, See if you wrote ng-click function then you need to write that function inside controller, & do DOM manipulation from the controller is not good way as per angular http://stackoverflow.com/a/15529412/2435473 – Pankaj Parkar Apr 14 '15 at 14:21

2 Answers2

0

You should run digest cycle manually after click event occurrence to update all scope bindings

.directive('closeMapMessage', function($log) {
  'use strict';
  return function(scope, element) {
    var clickingCallback = function() {
      angular.element('.map').fadeOut("slow");
      scope.$apply();
    };
    element.bind('click', clickingCallback);
  };
})
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
0

From the current snippet of code, it's hard to tell why you're not using a modal solution tailored for Angular, i.e. AngularUI's modal.

However, in your current code, you're attaching a click event to the element outside of Angular's awareness. That's why clicking on the element will not have effect until the next $digest cycle has run. Also, in Agular you normally don't use directives the way you're trying to do. I would suggest updating the directive to also provide the HTML and then use the ng-clickattribute to attach the event handler via Angular.

Update your directive's code to:

.directive('closeMapMessage', function($log) {
  'use strict';
  return {
      restrict: "AE",
      link: function(scope, element) {
         scope.closeModal = function() {
             angular.element('.map').fadeOut("slow");
             scope.showInstructionModal = false; // probably need to put this in a $timeout for example to show the fading of the element
         };
      },
      template: '<div class="close-map-msg ok-got-it-footer" ng-click="closeModal()">Ok, got it.</div>'
  };
})

And then update your HTML accordingly:

<div class="msg-mobile" ng-show="showInstructionModal">
  <close-map-message></close-map-message>
</div>
thomaux
  • 19,133
  • 10
  • 76
  • 103