0

In this PLUNK I have a div with an ng-show element that invokes a show() function that returns false. Therefore, I expect the div not to be displayed.

Also, see that the show() function is invoked twice (the console.log shows the sh variable twice). How to fix this?

Javascript

var app = angular.module('app', []);

app.directive('mydir', function ($compile) {

    var directive = {};

    directive.restrict = 'EA';

    directive.scope = {
         control: '='
    };

    directive.template = '<div id="root"></div>';

    directive.link = function (scope, element, attrs) {

      var sh = false;     
      var wrap = angular.element('<div id="wrap" ng-show="show()"></div>');
      wrap.attr('sh', sh);  
      var wrapc = $compile(wrap)(scope)
      element.append(wrapc); 

      scope.show = function() {
        var elem = angular.element( document.querySelector( '#wrap' ) );
        var sh = elem.attr('sh');
        console.log(sh); // <-- should log false only once, not twice
        return sh;
      }


    };

    return directive;

});

HTML

<mydir></mydir>
ps0604
  • 1,227
  • 23
  • 133
  • 330

1 Answers1

1

The problem why the div is displayed is because you read the sh value from attr and by doing so it becomes a string.

wrap.attr('sh', sh);

This line actually sets the attribute sh to "false" (string) and not false. And then the get function elem.attr('sh'); returns "false" as a string. And a not-empty string is truthy in javascript therefore it evaluates to true.

Replace:

 var sh = elem.attr('sh');

with a string comparison:

 var sh = (elem.attr('sh') == "true");

and it should work

That show is called twice is intended behaviour. Look here for details: Controller function getting called twice using ng-show

Community
  • 1
  • 1
x4rf41
  • 5,184
  • 2
  • 22
  • 33