0

I understand that Angular controllers should try not to perform heavy logic calculations.

I have a function within my controller that gets a list of 12months from the current month:

app.controller("MyController", function($scope) {

    $scope.getLast12Months = function () {

        var date = new Date();
        var months = [],
            monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
        for(var i = 0; i < 12; i++) {
            months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());

            // Subtract a month each time
            date.setMonth(date.getMonth() - 1);
        }
        $scope.months = months;

        return months;
    }


});

And displayed in my HTML via:

<th ng-repeat="months in getLast12Months()">{[{ months }]}</th>

Ive tried putting this into a directive via:

app.directive("ngGetLast12Months", function () {
return function ($scope) {

var date = new Date();
     var months = [],
            monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
        for(var i = 0; i < 12; i++) {
            months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());

            // Subtract a month each time
            date.setMonth(date.getMonth() - 1);
        }
        $scope.months = months;

        return months;
    }
});

And in the HTML:

<th ng-get-last-12-months>{[{ months }]}</th>

I can see my directive is being triggered via a console.log, but the output is appearing as:

["May 2014","Apr 2014","Mar 2014","Feb 2014","Jan 2014","Dec 2013","Nov 2013","Oct 2013","Sep 2013","Aug 2013","Jul 2013","Jun 2013"]

Rather than the ng-repeat fashion displaying as:

May 2014 Apr 2014 Mar 2014 Feb 2014 Jan 2014 Dec 2013 Nov 2013 Oct 2013 Sep 2013 Aug 2013 Jul 2013 Jun 2013


UPDATE Based on Engineer's Example

However seeing: Error: [$compile:tplrt] errors.angularjs.org/1.2.8/$compile/…

app.directive('ngGetLast12Months', function () {
return {
  replace: true,
  restrict: 'EA',
  template: '<th ng-repeat="month in months">{[{ month }]}</th>',
  link: function ($scope) {
    var date = new Date();
    var months = [], monthNames = [
        'Jan',
        'Feb',
        'Mar',
        'Apr',
        'May',
        'Jun',
        'Jul',
        'Aug',
        'Sep',
        'Oct',
        'Nov',
        'Dec'
      ];
    for (var i = 0; i < 12; i++) {
      months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
      // Subtract a month each time
      date.setMonth(date.getMonth() - 1);
    }
    $scope.months = months;
    return months;
  }
};
});
3
  • 1
    You probably need a service, not a directive. Commented May 23, 2014 at 12:06
  • 1
    problem with th I guess Commented May 23, 2014 at 13:17
  • @Skeptor - You're right, the <th> is causing that error, <div> works fine. I need it in a <th> however. Commented May 23, 2014 at 13:53

3 Answers 3

1

Here is the jsfiddle to this , http://jsfiddle.net/qF3KL/

This worked for me

html

<ng-get-last-12-months></ng-get-last-12-months>

js

.directive('ngGetLast12Months', function() {
    return {
        restrict: 'EA',
        template: '<th ng-repeat="month in months">{{month}}</th>',
        controller: function($scope) {
            var date = new Date();
            var months = [],
                monthNames = [
                    'Jan',
                    'Feb',
                    'Mar',
                    'Apr',
                    'May',
                    'Jun',
                    'Jul',
                    'Aug',
                    'Sep',
                    'Oct',
                    'Nov',
                    'Dec'
                ];
            for (var i = 0; i < 12; i++) {
                months.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
                // Subtract a month each time
                date.setMonth(date.getMonth() - 1);
            }
            $scope.months = months;
        }
    };
});
Sign up to request clarification or add additional context in comments.

1 Comment

strangely some reason , I am not able to make it work in local
1

Create directive like this:

app.directive("ngGetLast12Months", function () {
    return {
        replace : true,
        restrict: 'EA',
        template: '<th ng-repeat="month in months">{[{ month }]}</th>',
        link: function ($scope) {
           //Your code which evaluates `months`
           $scope.months = months;
        }
    };
});

2 Comments

im getting the following error trying the above: Error: [$compile:tplrt] errors.angularjs.org/1.2.8/$compile/… Have updated my question with a fuller version of your directive example.
should i be calling this in my HTML via: <ng-get-last-12-months></ng-get-last-12-months>
1

I don't see a reason why this should be in a directive. this is code that should be in a service. Then a controller can expose it on the scope and the html can still use ng-repeat to show it.

The reason why your directive is giving a different response, is because it works in a different way than ngRepeat. ngRepeat uses the inner html as a template and executes it every iteration of the loop you give it. So it clones that bit of DOM for every element in the array and then interpolates the value. Your directive just builds an array and outputs that array directly, so you get a json version of it in your DOM.

If you really want to do this in a directive, I would keep it easy and use the template option of directives. That will allow you to use ngRepeat to iterate over the values you calculate in the link function of your directive.

1 Comment

because this answer was given before the "update" part of the question. and if you look, you can see that he was doing <th ng-get-last-12-months>{[{ months }]}</th> in the html without any ng-repeat over the months in the directive template(there was no directive template).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.