Reputation: 5091
I have some Angular 1.4 code I've inherited, which has some bizarre scope issues I'm trying to tidy up - and I'm stuck on a particular one.
I have an ES6 Class controller (Babelified) - in it, I have a method like this
save(data) {
this.validate(data);
.... do some more stuff
}
I also have a View and model and html and all that good stuff. In it I have a custom directive for radio buttons - like this
<radio onupdate="vm.save" data="model.myradio1" />
My Radio directive seems to have two bindings for onupdate & data
.directive('radio', () => {
return {
restrict: 'E',
replace: true,
templateUrl: 'radio',
scope: {
data: '=',
onupdate: '='
}
};
})
the template contains
ng-click="radio.onupdate($parent.data);" <-- This looks suspect but no idea what it does!
However - this then explodes in ways I wouldn't have expected:
this.validate is not a function
I can see how this happened - this
now refers to the radio buttons scope. But how do I fix it? I'm pretty new to Angular.
Upvotes: 1
Views: 428
Reputation: 193311
In order to invoke a controller method from the directive you need to create a "reference" function with &
scope configuration:
.directive('radio', () => {
return {
restrict: 'E',
replace: true,
templateUrl: 'radio',
scope: {
data: '=',
onupdate: '&'
}
};
})
Then from directive template you need to call it like this:
ng-click="onupdate({data: $parent.data});"
And finally the usage of the radio directive becomes:
<radio onupdate="vm.save(data)" data="model.myradio1" />
Upvotes: 1
Reputation: 26
This is very common problem, when you use HTML element on*** attribute to register listeners. You have to bind controller context to listener function.
<radio onupdate="vm.save.bind(vm)" data="model.myradio1" />
I hope it will work for you.
Upvotes: 0
Reputation: 4681
Hello I stick to your question title 'how to call controller function from directive'.
I've made an example that uses a <select>
element and calls the controller function $scope.filterHall()
to send the selected object, whenever the user changes value.
Directive (i get the changeHall function and i call it into the template,see below ):
.directive('eventHallsList', function($timeout, $log, $http, $compile) {
return {
restrict: 'AE',
replace: true,
scope: {
changeHall: '&',
items: '=',
model: '='
},
templateUrl: 'mytemplate.tpl.html',
link: function(scope, element, attrs) {
}
}
});
Template: Into the select element everytime the user selects a value, i call the changeHall()
which is bind to the controller's function $scope.filterHall()
, and it pass the object.
<select style="color:#337ab7"
ng-change="changeHall({value:model})" ng-model="model"
ng-options="item as item.name for item in items">
<option value=""> choose hall</option>
</select>
live example : http://plnkr.co/edit/iCS0blQjceA4tIIb8bUV?p=preview
Hope helps, good luck.
Upvotes: 0