2

I have been trying to figure this out and did some searches but the results I find always seem to address issues that happen between directives and controllers.

I have a problem within a directive. I think I am not understanding scope correctly.

I have a directive that looks like this:

mb.directive("plainText", function() {
    return {
        restrict: 'E',
        scope: {
            value: "@",
        },
        templateUrl: 'plainText.html',
        link: function(scope, element, attrs){

            scope.view = false;

            element.bind("click", function() {

                if ( scope.view == false ) {
                    scope.view = true;
                    console.log(scope.view);
                } else {
                    scope.view = false;
                    console.log(scope.view);
                }
            })

            scope.value = attrs.value;
        }
    }
})

and a HTML template like this:

<div>{{value}}</div> // this part of the directive always stays visible

<div ng-show="{{view}}"> // THIS LINE NEEDS TO RESPOND TO THE CLICK
    <input type="text" ng-model="value">
    <br/>
    <div class="btn btn-default" ng-click="save()">Save</div>
    <div class="btn btn-default" ng-click="cancel()">Cancel</div>
</div>

My console log shows that the click event is being fired by the scope value but "view" is not being applied to the div that needs to show and hide.

Could someone explain what I am doing wrong?

CDspace
  • 2,639
  • 18
  • 30
  • 36
GRowing
  • 4,629
  • 13
  • 52
  • 75

1 Answers1

1

The template should be just

<div ng-show="view">
    <input type="text" ng-model="value">
    <br/>
    <div class="btn btn-default" ng-click="save()">Save</div>
    <div class="btn btn-default" ng-click="cancel()">Cancel</div>
</div>

the ng-show directive watches for the changes in the scope variable passed via the attribute so you need to pass the scope variable name instead of the variable by interpolating it.

Also you need to call scope.$apply() in the jQuery click handler

        element.bind("click", function () {
            scope.view = !scope.view;
            console.log(scope.view);

            if (!scope.$$phase && !scope.$root.$$phase) {
                scope.$apply()
            }
        })

Demo: Fiddle

Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • The first line
    {{value}}
    I need visible at all times and when I click on the visible part of the directive the rest of the directive needs to hide or show.. When I use view in place of {{view}} still nothing happens.
    – GRowing Jan 29 '14 at 03:46
  • @ng-jslearningcurve also you can do it without the click handler - you can use [ng-click](http://docs.angularjs.org/api/ng.directive:ngClick) directive like http://jsfiddle.net/arunpjohny/YnpZS/3/ – Arun P Johny Jan 29 '14 at 03:58
  • Thank you so much.. I need to use the click handler because there is more stuff going on in it but I really appreciate both examples. Could you maybe explain $$phase and $root.$$phase a bit more. I fiddled with $scope.$apply but it was at the level of fiddling .. – GRowing Jan 29 '14 at 04:08
  • @ng-jslearningcurve then try a click handler like http://jsfiddle.net/arunpjohny/YnpZS/4/ – Arun P Johny Jan 29 '14 at 04:12
  • @ng-jslearningcurve when you make changes to a scope state that is evaluated in the digest cycle... if a method is invoked by ngjs then at the end of the method invokation the digest cycle will be invoked by it... but in your case the click handler is invoked by jQuery so ng is unaware about any changed done to the scope so your ui will not get updated based on the new scope changes... when you call `$apply()` it will internally invoke the digest cycle thus updating the ui – Arun P Johny Jan 29 '14 at 04:15
  • @ng-jslearningcurve also see http://stackoverflow.com/questions/15112584/using-scope-watch-and-scope-apply and http://stackoverflow.com/questions/12729122/prevent-error-digest-already-in-progress-when-calling-scope-apply – Arun P Johny Jan 29 '14 at 04:17
  • ahh! I see. I keep having problems with scope.. in general.. it is frustrating sometimes.. This helps a great deal! Thank you. – GRowing Jan 29 '14 at 04:25