Reputation: 57
I know that this question seems to be recurrent, but I haven't find an answer in other topics.
So, I'm knew to Angular et I have a problem, my first button don't seems to trigger the function when clicked.
I'm kind of ashamed to ask this question because it's seems so newby to link a button to a function, but ... can you help me please ?
My code:
index.html:
...
<div>
<validate-bill/>
</div>
...
directives.js
app.directive('validateBill', function() {
return{
restrict : 'E',
template : "<button ng-click='checkBill()'>Valider</button>"
};
});
controllers.js
var BillChecker = function($scope, billData,billChecker) {
$scope.data = billData.billOne;
$scope.checkBill = function(){
billChecker.validateBill();
};
};
app.controller("BillChecker",BillChecker);
services.js
app.factory('billData', function() {
return {
billOne: {
entityName: 'entity',
clientName: 'client',
products: [
{"name":"p1","price":50},
{"name":"p2","price":150},
{"name":"p3","price":120},
{"name":"p4","price":50}
],
email: '[email protected]',
status : false
}
}
});
app.factory('billChecker',function () {
return{
validateBill:function()
{
alert("Im here ");
}
}
});
Upvotes: 2
Views: 75
Reputation: 535
Firstly, when using a custom element directive, you should always close your tag using a second tag i.e.
<my-custom-tag></my-custom-tag>
NOT
<my-custom-tag/>
because many browsers will not recognize the second thing.
Now to your issue, any functions called within your directive "validateBill" will be looking for their definitions within that directive's controller. This means that, if you want to call a function from within a directive, you must define a controller that contains said function linked to your directive's scope. Example below:
app.directive('validateBill', function() {
return{
restrict : 'E',
template : "<button ng-click='checkBill()'>Valider</button>",
controller : function($scope) {
$scope.checkBill = function() {....};
}
};
});
Now, if you would like the function called within that directive to call something in your main app controller, you must pass your directive in a callback to its scope using the scope attribute in your directive. Example below:
app.directive('validateBill', function() {
return{
restrict : 'E',
scope : {callback : '&'}
template : "<button ng-click='checkBill()'>Valider</button>",
controller : function($scope) {
$scope.checkBill = function() {$scope.callback()()};
}
};
});
usage from main html:
<validate-bill callback="MainCtrl.checkBill"></validate-bill>
TLDR: Creating custom directives also creates a separate scope that functions called within that directive will look for their definitions within. If you wish to call methods in a parent scope, it is best to pass those in as attributes to your directives as it will make your application more modular in the long-run.
I would highly suggest reading this (http://www.codelord.net/2016/05/13/understanding-angulars-and-binding/) as an explanation for bindings and callbacks withing angularJS.
Upvotes: 2