1

I have two directives, for the sake of simplicity I have reduced my problem to the following:

Directive 01 : handles authentication

it is responsible for opening modals / windows and getting user authenticated.

angular
.module('app.directives')
.directive('requiresLogin', function(){       
     return {
         restrict : 'A',
         link : function() { //..}
     }
})

Directive 02 : performs specific action

angular
.module('app.directives')
.directive('like', function(){

     return {
         restrict : 'A',
         link : function() { //..}
     }
})

Both directive 01 and 02 bind click events.

I am bit confused about the design of two directives.

I could make the second directive a child of the first one and get communication between the directive, which to some extent makes sense as the single responsibility of each directive is maintained under this pattern. However all my future directives that would need authentication will be children of the first directive.

My Question is :

How can prevent the second directive (actual action) based on the result of first "authenticating" directive ? Is there any other way of doing this without making a "parent-child" relation between them ?

1
  • Sorry, have you found my answer helpful? Commented Sep 10, 2014 at 11:29

2 Answers 2

2

You can use "require" definitly well explained in the following post :

How to require a controller in an angularjs directive

In your context you could do:

.directive('requirelogin', function() {
    return {
        scope: true,
        controller: function() {
            var isLogged = false;

            this.isLogged = function() {
                if(isLogged) return isLogged; 
                alert("You are not logged!");
            };

            this.login = function(){
                isLogged = true;            
            };
        }
    };
})

.directive('like', function() {
    return {
        scope: true,
        require: '^requirelogin',
        link: function(scope, element, attrs, loginCtrl) {
            scope.loginCtrl = loginCtrl;
            scope.sayILike = function(){
                if(scope.loginCtrl.isLogged()){
                    alert('I like');
                }
            };

            scope.login = function(){
                scope.loginCtrl.login();
            };
        }
    };
});

Working : http://jsfiddle.net/bennekrouf/nq9g33Lt/25/

Sign up to request clarification or add additional context in comments.

2 Comments

ok... is there some explanation for this downvote ? sharing a controller between 2 directives is useful for saying that on depends from the other.
Could you develop your answer a bit more?
0

Only add the "action" directive and inject an auth service to it:

http://jsfiddle.net/coma/dby686ab/

Logic

app.factory('user', function() {

    var roles = ['user'];

    return {
        hasRole: function(role) {

            return !role || roles.indexOf(role) > -1;
        }
    };
});

app.directive('like', function(user) {

    return {
        restrict: 'A',
        link    : function(scope, element, attrs) {

            element.on('click', function () {

                if (user.hasRole(attrs.authRole)) {

                    element.addClass('liked');
                    element.off('click');

                } else {

                    alert('Unauthorized.');
                }
            });
        }
    };
});

View

<a like="">Dogs</a>
<a like="" auth-role="user">Birds</a>
<a like="" auth-role="admin">Whales</a>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.