Reputation: 858
In this directive i want to be able to show the Month of Birth for each user in the Array on ng-repeat. How can i access the getBirthMonth(DOB) method in the Controller from the Directive? Each user's DOB is passed as an argument to the method during each iteration
i.e
<p ng-repeat="x in customerInfo">
Name: {{x.name}} Address: {{x.address}}
<span ng-init="birthMonth = getBirthMonth(DOB)"> {{birthMonth}}</span>
</p>
Here is a Plunkr: https://plnkr.co/edit/6TBqsjDllTCUAPQc9BzL?p=preview
Desired Result: Name: John Address: 22 Infinite loop Birth Month: February
Upvotes: 0
Views: 62
Reputation: 901
To answer your question as appropriately as possible, I've forked your provided plunker and made it work as expected.
https://plnkr.co/edit/hN0AYYxLGxpl7e2sWhSw?p=preview
Some things to note: You can pass in your data and functions to the directive. I've used the bindToController on the directive in order to use modern practices for bindings in the DOM. (See https://github.com/angular/angular.js/wiki/Understanding-Scopes for more info about scopes)
The updated directive definition is:
restrict: 'E',
scope:{},
bindToController: {
customerInfo: '=info',
calcDob: "&"
},
templateUrl: 'my-customer-plus-vojta.html',
controller: function(){
},
controllerAs: "$ctrl"
And the use of the directive is:
<my-customer info="names" calc-dob="getBirthMonth"></my-customer>
I also changed the directive template a bit, using the new controllerAs value, and removed the ngInit
Name: {{x.name}} Address: {{x.address}}: {{$ctrl.calcDob()(x.DOB)}}
Upvotes: 0
Reputation: 150
What you are trying to do is an antipattern. Try to encapsulate the specific functionality in a service. This way you can reuse it through the application:
angular.module('docsIsolationExample', [])
.service('getBirthMonth', [function() {
return function (DOB) {
var month = [];
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
var d = new Date(DOB),
n = month[d.getMonth()];
return n; // returns monthName i.e February
}
}])
A working example: https://plnkr.co/edit/RlSvfNo5qgjblHImYbnc
You don't need to use the ng-init, only use the function instead:
<span>{{getBirthMonth(x.DOB)}}</span>
Try the Angular 1 Style Guide by johnpapa: https://github.com/johnpapa/angular-styleguide/tree/master/a1 - it produces much better readable code.
Upvotes: 0
Reputation: 14417
You just create a service for it to sit in ( plnkr ) :
.service('birthMonth', function () {
this.getBirthMonth = function (DOB) {
var month = [];
month[0] = "January";
month[1] = "February";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";
var d = new Date(DOB),
n = month[d.getMonth()];
return n; // returns monthName i.e February
}
});
Directive:
.directive('myCustomer', ['birthMonth', function(birthMonth) {
return {
restrict: 'E',
scope: {
customerInfo: '=info'
},
templateUrl: 'my-customer-plus-vojta.html',
link: function (scope) {
scope.getBirthMonth = birthMonth.getBirthMonth;
}
};
}])
HTML:
<p ng-repeat="x in customerInfo">
Name: {{x.name}} Address: {{x.address}}
<span> {{getBirthMonth(x.DOB)}}</span>
</p>
Upvotes: 3