Reputation: 6831
In the angular directive I have this
app.directive('myDir', function () {
return {
restrict: 'E',
scope: true,
template:'<div>{{myindex}}</div>',
link: function(scope, element, attrs){
console.log('test', scope.myindex)
},
controller: 'myDirController'
};
})
I use like this
<my-dir> </my-dir>
Now as I want to use it in different templates, I have one function which I want to call like this
// this is inside myDirController
test: function($scope){
$scope.myFunction();
}
Now basically I want to call $scope.myFunction();
This works fine if I have $scope.myFunction();
defined in parent controller.
Buy it's not reusable as in my other controller I want to call $scope.myFunction2();
.
So I want something so that I can pass the function name in directive
<my-dir fname="myFunction"> </my-dir>
and that gets called in my directive
The thing is I can't use isolated scope as I need to have access to parent $scope
Upvotes: 2
Views: 589
Reputation: 48659
i want to call $scope.myFunction();
[my directive is] not reusable as in my other controller i want to call $scope.myFunction2();
SO i want something so that i can pass the function name in directive:
<my-dir fname="myFunction"> </my-dir>
1) The attributes in your custom tag are available in the link function, so you can save the value of the fname attribute for future use:
link: function(scope, element, attrs){
scope.data = {fname: attrs.fname};
},
2) An object's properties can be retrieved using dot notation, e.g. $scope.fname
, but the properties can also be retrieved using array notation, e.g. $scope[fname]
, where fname is a string. And if $scope[fname]
is a function, you can execute it by writing $scope[fname]()
:
app.controller('MyDirCtrl', function($scope) {
$scope.test = function() {
var fname = $scope.data.fname;
$scope[fname](); //fname property not found in current scope, so parent scope is searched
};
});
....
<body ng-app="myApp">
<div ng-controller="Ctrl1">
<my-dir fname="funcInCtrl1"></my-dir>
</div>
<div ng-controller="Ctrl2">
<my-dir fname="funcInCtrl2"></my-dir>
</div>
...
var app = angular.module('myApp',[]);
app.controller('Ctrl1', ['$scope', function($scope) {
$scope.funcInCtrl1 = function() {
console.log('funcInCtrl1 called...');
};
}]);
app.controller('Ctrl2', ['$scope', function($scope) {
$scope.funcInCtrl2 = function() {
console.log('funcInCtrl2 called...');
};
}]);
app.controller('MyDirCtrl', ['$scope', function($scope) {
$scope.test = function() {
var fname = $scope.data.fname;
$scope[fname]();
};
}]);
app.directive('myDir', function () {
return {
restrict: 'E',
scope: true,
template:'<div ng-click="test()">click me</div>',
link: function(scope, element, attrs){
scope.data = {fname: attrs.fname};
},
controller: 'MyDirCtrl',
}
})
And, here it is with Controller as syntax:
<body ng-app="myApp">
<div ng-controller="Ctrl1 as ctrl1">
<my-dir fname="ctrl1.funcInCtrl1"></my-dir>
</div>
<div ng-controller="Ctrl2 as ctrl2">
<my-dir fname="ctrl2.funcInCtrl2"></my-dir>
</div>
...
var app = angular.module('myApp',[]);
app.controller('Ctrl1', function() {
this.funcInCtrl1 = function() {
console.log('funcInCtrl1 called...');
};
});
app.controller('Ctrl2', function() {
this.funcInCtrl2 = function() {
console.log('funcInCtrl2 called...');
};
});
app.controller('MyDirCtrl', ['$scope', function($scope) {
this.test = function() {
var fnames = $scope.data.fname.split('.');
var ctrl_name = fnames[0];
var func_name = fnames[1];
$scope[ctrl_name][func_name]();
};
}]);
app.directive('myDir', function () {
return {
restrict: 'E',
scope: true,
template:'<div ng-click="mydirCtrl.test()">click me</div>',
link: function(scope, element, attrs){
scope.data = {fname: attrs.fname};
},
controller: 'MyDirCtrl',
controllerAs: 'mydirCtrl'
}
})
Upvotes: 2
Reputation: 8090
You could use a factory and create different directives with this factory that use your specific function.
module.service('DirectiveFactory', function() {
this.create = function(fn) {
return {
restrict: 'E',
scope: true,
template:'<div>{{myindex}}</div>',
link: function(scope, element, attrs){
console.log('test', scope.myindex)
},
controller: function($scope) {
// your specific function
fn();
}
};
};
});
module.directive('my-dir-1', function(DirectiveFactory) {
function fn1() {
console.log('my special function call1');
}
return DirectiveFactory.create(fn1);
});
module.directive('my-dir-2', function(DirectiveFactory) {
function fn1() {
console.log('my special function call2');
}
return DirectiveFactory.create(fn2);
});
In your template you'd use:
<my-dir-1></my-dir1>
<my-dir-2></my-dir2>
Upvotes: 0