1

I have a directive whose 'config' attribute value I need to access inside my directive controller. Since the controller constructor get executed first,communication from controller to link is possible but not vice versa. What should be the best way to achieve this? I have considered the following approaches

1)Add the variable to scope- That would in my opinion pollute the scope,making the variable accessible every where else where the scope is being shared.

2)Use $broadcast Again the same issue as above

3) Pass a callback function on controller's this and call it from the link function with config as its argument

4)Pass the value through a service- In my case I have multiple such directives that would need to pass date through this service

Or is there some better approach that I am missing out for doing this?

module.directive('myDirective',function(){

return{
 restrict:'E',
 templateUrl:'path/to/html',
 link:function(scope,iElement,iAttrs,controller){

  var config=iAttrs.config;
//How to access this value inside the directive controller?

},
controller:function($scope){
//the directive attribute 'config' is required here for some larger computations which are not
//manipulating the DOM and hence should be seperated from the link function
})
2
  • 1
    Did you try to inject $attrs in your controller? Commented Jun 28, 2015 at 16:06
  • Any link describing its usage would be appreciated.Documentation isn't very clear about $attrs Commented Jun 28, 2015 at 16:18

1 Answer 1

3

There you can use isolated scope concept where you create isolated scope inside your controller & that would not be prototypically inherited from its parent scope. For that you need to use scope: { ... } inside your directive option. There are three options to pass scope value inside a directive through attribute

  1. @ : One way binding
  2. = : Two way binding
  3. & : Expression

In your case first two cases would be fine that are depends which one you need to use. If you just want to pass the value of scope variable to the directive in that case you could use 1st approach which would be @ one way binding.

If you want to update the variable in both directive as well as controller from where it come i.e. nothing but two way binding, then you need to use =

I think = suits in your case so you should go for =

Markup

<my-directive config="config"></my-directive>

Directive

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    scope: {
      config: '='
    },
    templateUrl: 'path/to/abc.html',
    link: function(scope, iElement, iAttrs, controller) {
      //here it will be access as scope.config
      console.log(scope.config);
    },
    controller: function($scope) {
      console.log($scope.config); //here also it would be available inisde scope
      //you could put a watch to detect a changes on config
    }
  }
});

Demo Plunkr

Update

As config value has been provide from the attribute with expression like {{}} so we could get those changes inside controller by putting [**$observe**][2] on $attrs. For that you need to inject $attrs dependency on your controller that will give you all the attributes collection which are available on directive element. And on the same $attrs object we gonna put $observe which work same as that of $watch which does dirty checking & if value gets change it fires that watch.

Directive

app.directive('myDirective', function() {
  return {
    restrict: 'E',
    templateUrl: 'path/to/abc.html',
    link: function(scope, iElement, iAttrs, controller) {
      //here it will be access as scope.config
      console.log(scope.config);
    },
    controller: function($scope,$attrs) {
      //you could put a watch to detect a changes on config
      $attrs.$observe('config', function(newV){
        console.log(newV);
      })
    }
  }
});

Updated Demo

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

10 Comments

I cant afford to create an isolate scope for this directive as it would devoid me of using parent scope variables directly.As I said I have a series of such directives that need to share a common scope.
@Abdul23 give me few minutes I'll create a code without isolated scope..first answer some question of me..do you have config information is stored in scope variable?
Yes I have it available in the parent scope,but to pass it as scope variable attribute using = would mean I have to create an isolate scope for it inside my directive which I want to avoid
@Abdul23 then why you don't directly access the value inside a controller from directive controller like $scope.config If you parent scope has config value in $scope.config
Its a complex situations.For some reasons I want my directive to be used like <my-directive config="expression to be parsed to find the data"></my-directive> and not like <my-directive></my-directive>.
|

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.