angularjsangularjs-directiveangular-ng-ifangularjs-compile

Angularjs directive conditional rendering without ng-if


I have a directive which I render only if my authentication service tells me so:

<div my-loggedin-directive ng-if="security.isAuthenticated()"></div>

The directive itself is quite empty :

.directive('myLoggedinDirective', [
    function() {
        return {
            templateUrl: 'modules/myLoggedinDirective.tpl.html',
            restrict: 'A',
            replace: true,
            link: function($scope) {
                 $scope.$on('$destroy', function() {
                     console.log('$destroy');
                 });
            }
        };
    }
]);

Since my directive should be always rendered when I'm logged in, the ngIf logic should be inside the directive declaration, and not in a ng-if (the directive without the ngIf would be totally broken).

How can I change the directive code (injecting the test on the security service inside the directive declaration) knowing that I want the same behavior as the ngIf ? :

I tried to use compile function and a watcher to watch security.isAuthenticated() without success


Solution

  • Declare extra directive attribute that will pass security object into your directive:

    <div my-loggedin-directive my-security='security'></div>
    

    And directive should include scope, make sure it uses two-way binding:

    .directive('myLoggedinDirective', [
    function() {
        return {
            scope: {
                security: "=mySecurity"
            }
            templateUrl: 'modules/myLoggedinDirective.tpl.html',
            restrict: 'A',
            replace: true,
            link: function($scope) {
                 $scope.$on('$destroy', function() {
                     console.log('$destroy');
                 });
    
                 $scope.$watch('security', function(newVal, oldVal) {
                     if (newVal.isAuthenticated()) {
                     // do something
                     } else {
                     // do something
                     }
                 });
            }
        };
    }
    

    ]);

    And now you can access $scope.security variable in your temple myLoggedinDirective.tpl.html

    <div ng-if="security.isAuthenticated()">...</div>