Reputation: 6015
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
})
Upvotes: 1
Views: 4817
Reputation: 136144
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
@
: One way binding=
: Two way binding&
: ExpressionIn 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
}
}
});
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);
})
}
}
});
Upvotes: 3