Reputation: 17711
This is a reduction of my directive:
app.directive('myDirective', function() {
return {
restrict: 'E',
replace: true,
template:
'<form name="form" action="{{action}}" method="post" target="_blank">' +
'<input type="hidden" name="item_name" value="{{itemname}}">' +
'</form>',
scope: {
action: '@action',
itemname: '@itemname',
},
link: function(scope, element, attrs) {
scope.action = attrs.action || 'http://www.example.com';
scope.itemname = attrs.itemname();
}
};
});
and I use it this way:
<div ng-if="itemWasSelected">
<my-directive
action="{{ 'http://www.example.com' }}"
itemname="itemNameBuildFunction"
/>
</div>
In my controller, I have:
$scope.itemNameBuildFunction = function() {
return $scope.value1 + $scope.value2;
};
I would expect my directive, when it is linked (it is inside an ng-if
clause, so, I mean, when the ng-if
condition evaluates to true), to call attrs.itemname()
$scope function, to assign scope.itemname variable in the controller's link function.
Instead, what I get is the error:
TypeError: attrs.itemname is not a function
Can you please give me some directions? As you can see, I'm quite confused, with angular directives... :-(
Upvotes: 0
Views: 2827
Reputation: 2092
Seems to me that you actually want '='
type which will take in javascript objects and (without requiring JSON.parse) allow you to use them in your scope. A function is javascript object which can be run using the ();
So the best solution is:
scope: {
action: '@',
itemname: '=',
},
This will allow you to take a callback for the item name and then run it in the scope as you see fit.
https://plnkr.co/edit/cKzLhP4SwHey266Flr5w?p=preview.
Also, how would someone submit the form you offer? It doesn't seem to make sense you should have a <input type='submit'/>
if you want to submit a hidden input name. Also, you probably want to use templateURL and include an HTML template instead of having a big dynamic form in you js.
Upvotes: 0
Reputation: 15292
You don't need this statement attrs.itemname()
.
Your function reference passed in directive is bind to to the variable itemname
on scope
that is passed as first parameter in link
function which isolated scope
Just change the statement from
scope.itemname = attrs.itemname();
To :
scope.itemname(); // this will call the function `itemNameBuildFunction`
EDIT :
You have used @
operator ofr binding function which is used in case passing primitive or object.You are passing function, so , you should use &
operator,will evaluate as function.
scope: {
action: '@action',
itemname: '&itemname',
}
EDIT 2:
Yous should passed function itemNameBuildFunction()
and not itemNameBuildFunction
<my-directive action="{{ 'http://www.example.com' }}"
itemname="itemNameBuildFunction()" />
Working Plunker
Upvotes: 2