Reputation: 4550
So I am trying to create a directive which will replace an element with HTML which includes an ng-click which calls a function created in $scope.
An example I made can be found at http://jsfiddle.net/adinas/wbfu9ox3/5/ My HTML is
<div ng-app="myapp" ng-controller="mycontroller">
{{greeting}}
<!--This works-->
<div xyz></div>
<!--This works-->
<div ng-click="dosomething('Click me 2')">Click me 2</div>
<!--The click added in the directive here does NOT work-->
<div abc mytext="Click me 3"></div>
My JS is
var myapp = angular.module('myapp',[]);
myapp.controller('mycontroller', ['$scope', function($scope) {
$scope.greeting = 'Hola!';
$scope.dosomething = function (what) {
alert(what);
};
}]);
//Works
myapp.directive('xyz', function () {
return {
template: '<div ng-click="dosomething(\'Click me 1\')">Click me 1</div>'
};
});
//Does not work
myapp.directive('abc', function () {
return {
template: '<div ng-click="dosomething(\''+attr.mytext+'\')">Click me 3</div>'
};
});
I made 3 elements. The first two show that A. without the directive the click work. B. a directive without using the 'dosomething' function also works.
The 3rd element which tries to pass a parameter to the 'abc' directive and also call the function fails.
How can I also pass a parameter and also use the function? Thanks.
Upvotes: 0
Views: 57
Reputation: 101748
Well, if you look in the console, you will see an error that shows why this is not working:
Error: attr is not defined
You're trying to access an attr
variable that doesn't exist.
The way to include attribute values in your directive template is to include them in the directive's scope:
scope: {
mytext: '@'
}
This means that there will now be a mytext
variable in the scope of the directive.
This creates a problem, however, since the use of the scope: {}
option creates an isolate scope for the directive, and this means that the enclosing controller's scope is not part of the directive's scope.
If feasible, the clean approach here is to also pass in the dosomething
function as a parameter of the directive:
<div abc mytext="Click me 3" action='dosomething'></div>
return {
template: '<div ng-click="action(mytext)">Click me 3</div>',
scope: {
mytext: '@',
action: '='
}
};
http://jsfiddle.net/jx1hgjnr/1/
But if that's not what you want to do and you really want to access dosomething
from the parent scope, one thing you can do is use $parent.dosomething
:
return {
template: '<div ng-click="$parent.dosomething(mytext)">Click me 3</div>',
scope: {
mytext: '@'
}
};
http://jsfiddle.net/c815sqpn/1/
Upvotes: 1
Reputation: 9486
Such directive should have isolated scope, so it can be used everywhere. That is simple directive that introduce two parameters: func and param.
app.directive('pit', function () {
return {
scope : {
func: '=',
param: '='
},
template: '<button ng-click="func(param)">Click me 3</button>'
};
});
And this is how u use it in html:
<div pit func="test1" param="test2"></div>
My plunker: http://plnkr.co/edit/YiEWchRPwX6W7bohV3Zo?p=preview
Upvotes: 1