2

I'm using a directive with the controllerAs syntax. I want to use 2 instances of that directive, which both need to have non shared data. My problem, it seems that there is only controller instance.

There seems to be the option to add to the directive declaration a scope : {}. But then I would be forced to use the scope based access?

Or is there any other way to still using the controllerAs/this syntax and enforcing angular to create 2 distinct controller object?

app.directive('createA', function() {
    return {
        restrict : 'E',
        templateUrl : '/template/createActivity',

        // using this to create 2 distinct scopes 
        // but then I can't use the this/caCtrl.data syntax?
        scope      : {},

        controller : function($scope, $rootScope) {

            // using this syntax to access data 
            // in tempate like {{ caCtrl.data }}
            this.data = '123';
        },
        controllerAs : 'caCtrl'

    };
});

2 Answers 2

3

I believe what you are looking for is the bindToController property of the directive. Check this blog post http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

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

Comments

2

I realize this question is quite old already but in case anyone stumbles upon it and needs a different solution, the "bindToController" property mentioned in the 1st answer didn't make it for me.

I had a similar scenario where I needed to instantiate multiple directives using the controllerAs syntax, this is how I solved it (applied to the example's directive). It might not be too elegant but it works.

app.directive('createA', function () {
    return {
        restrict : 'E',
        templateUrl : '/template/createActivity',

        // using this to create 2 distinct scopes 
        // but then I can't use the this/caCtrl.data syntax?
        // scope      : {}, //do not use isolated scope
        controller: function ($scope, $rootScope, $attrs) {

            var controllerAsName = !!$attrs.ctrlName ? $attrs.ctrlName : 'caCtrl';

            var self = $scope[controllerAsName] = {};

            // using this syntax to access data 
            // in tempate like {{ caCtrl.data }}
            self.data = '123';
        },
        // controllerAs : 'caCtrl' //do not specify controllerAs since you are "manually handling" it
});

When using your directive in the HTML you'd use it like this:

<create-a ctrl-name="foo">foo.data</create-a>
<create-a ctrl-name="bar">bar.data</create-a>

I don't know what the markup for the directive's template is, therefore my solution might not make sense for you, but you get the idea.

2 Comments

I find it surprising that Angular makes the controller shared across directive instances. Can anyone explain why this would be more desirable as default behaviour instead of having directives have their own controllers and data?
If you need to have different instanced data, just use scope: {} and create an isolated scope, then use the scope object to store data. Otherwise, do what the OP does and pass in an extra param and store it as a map at the controller level.

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.