Reputation: 15703
I'm using Anguljarjs 1.4x. I'm trying to pass a value from an external function back to a directive. I've done some similar things before, but for some reason the function parameter is not coming back to my controller.
Here is some working plunker code I had to pass an external function to a directive. What I want to do now is add in a single text parameter value.
index.html
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="1.4.2" src="https://code.angularjs.org/1.4.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div id="app" ng-app="app">
<div ng-controller="mainCtrl">
<my-directive ctrl-fn="ctrlFn()"></my-directive>
</div>
</div>
</body>
</html>
myPage.html
<div>
<button ng-click='ctrlFn()'>Click Here</button>
</div>
script.js
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope){
$scope.count = 0;
$scope.ctrlFn = function() {
console.log('In mainCtrl ctrlFn!');
$scope.count += 10;
console.log("count is: " + JSON.stringify($scope.count));
};
});
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
// template: "<div><button ng-click='ctrlFn()'>Click Here</button></div>",
templateUrl: "./myPage.html",
link: function(scope, element, attributes) {
scope.ctrlFn();
console.log("In link!");
}
};
});
When the app runs I get this: In mainCtrl ctrlFn!
count is: 10
In link!
After I click the button I get this: In mainCtrl ctrlFn!
count is: 20
As I said this all worked, until I added in a parameter. All I'm trying to do is add in a text param, but I'm getting an error when I tried this in myPage.html:
Error: cannot use 'in' operator to search for 'ctrlFn' in 'hello'
<button ng-click='ctrlFn('hello')'>Click Here</button>
I added in a text value to my ng-click function and then created a param in the other places I have that function listed.
Any ideas as to how to do this?
Upvotes: 1
Views: 569
Reputation: 48968
In the directive template use:
template: `
<button ng-click="ctrlFn({$event: 'hello'})">
Click Here
</button>
`,
Use the directive as so:
<my-directive ctrl-fn="ctrlFn($event)"></my-directive>
The DEMO on PLNKR
var app = angular.module('app', []);
app.controller('mainCtrl', function($scope){
$scope.count = 0;
$scope.ctrlFn = function(value) {
$scope.count += 10;
$scope.message = value;
};
});
app.directive('myDirective', function() {
return {
restrict: 'E',
scope: {
'ctrlFn' : '&'
},
template: `
<div>
<button ng-click="ctrlFn({$event:'hello'})">
Click Here
</button>
</div>
`,
link: function(scope, element, attributes) {
scope.ctrlFn();
}
};
});
<script src="//unpkg.com/[email protected]/angular.js"></script>
<body ng-app="app" ng-controller="mainCtrl">
<my-directive ctrl-fn="ctrlFn($event)"></my-directive>
message={{message}}<br>
count={{count}}
</body>
With expression ("&"
) binding, define the attribute:
<my-directive my-func="parentFn($event)">
</my-directive>
Invoke the function with the $event
parameter defined as a local:
export default function myDirective() {
'ngInject';
return {
restrict: 'A',
scope: {
'myFunc': '&'
},
templateUrl: "./myPage.html",
controller: myCtrl
};
function myCtrl($scope) {
'ngInject';
console.log("In myCtrl!");
var answer = $scope.myFunc({$event: "Hello"});
console.log(answer);
}
}
Upvotes: 1
Reputation: 1420
Here is a working plunker of your code.
https://next.plnkr.co/edit/TWQEUUWq6h55uOIXDbuR
Basically, you need to remove the parenthesis from the directive
<my-directive ctrl-fn="ctrlFn"></my-directive>
Then unwrap the function (in the directive) before you call it.
scope.ctrlFn = scope.ctrlFn();
This answer provides more information about unwrapping the function.
https://stackoverflow.com/a/27300517/1896352
Upvotes: 1