ps0604 ps0604 - 5 months ago 22
AngularJS Question

`ng-show` invoking function does not work

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>

Answer

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