0

I'm creating custom directive for all h1-h6 elements. All directives body are the same: they set random color for h-element.

Here is my working code - ugly and DRY

angular.module('example', []);

angular.module('example').factory('randomColor', function () {
    return function () {
        var colors = ['#FF6A88', '#39FF82', '#7AD5D5', '#DFAF01'];
        var randomPick = parseInt(Math.random() * colors.length);
        return colors[randomPick];
    };
});


angular.module('example').directive('h1',['randomColor', function (randomColor) {
    return {
        restrict: 'E',
        link: function (scope, element) {
            $(element).css({ color: randomColor() });
        }
    };
}]);

angular.module('example').directive('h2',['randomColor', function (randomColor) {
    return {
        restrict: 'E',
        link: function (scope, element) {
            $(element).css({ color: randomColor() });
        }
    };
}]);

//the same for h3-h6

You can check this code here: Plunker - DRY version

Is possible to achieve something like this?

angular.module('example').directive(['h1','h2','h3','h4','h5','h6'],['randomColor', function (randomColor) {
    return {
        restrict: 'E',
        link: function (scope, element) {
            $(element).css({ color: randomColor() });
        }
    };
}]);

3 Answers 3

3

Theres many ways around it, it's just JavaScript after all...

Array foreach would be one option, you can also look to the angular core where actually does something to minimize the boilerplate.

var mod = angular.module('example');
['h1','h2','h3', 'h4','h5','h6'].forEach(function(tag) {
mod.directive(tag,[ 'randomColor', function(randomColor) {
  return {
    restrict: 'E',
    link: function (scope, element) {
      //Note: for angular 1.x element is already a JQuery or JQLite object, 
      // so no need for hte $() wrapping here. 
      // You need to load JQuery before angular 
      // for it to be a full JQuery object.
      element.css({color: randomColor()});
    }
  };
}]);
});
Sign up to request clarification or add additional context in comments.

1 Comment

This is the solution also used in AngularJS itself for components that are very alike. I'd go with this.
3

Have you tried something like this?

var app = angular.module('example', []);

var fn = function(randomColor) {...};

app.directive('h1', ['randomColor', fn]);
app.directive('h2', ['randomColor', fn]);
...

2 Comments

I know this is improvement but not strict answer on my question
Using the exact syntax in your question, no, it's not possible. What you'll get are answers with creative ways to solve the problem using standard language features
0
var mod=angular.module('example', []);

mod.factory('randomColor', function() {
    return function(){
                var colors = ['#FF6A88', '#39FF82', '#7AD5D5', '#DFAF01'];
                var randomPick = parseInt(Math.random()*colors.length);

                return colors[randomPick];
            };
});

var headerDirective=[ 'randomColor', function(randomColor) {
  return {
    restrict: 'E',
    link: function (scope, element) {
      $(element).css({color: randomColor()});
    }
  };
}];

['h1','h2','h3', 'h4','h5','h6'].forEach(function(tag) {
      mod.directive(tag,headerDirective); 
 });

Comments

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.