DEV Community

Oke Vese
Oke Vese

Posted on

2 1

How I Styled AngularJS Components by Routes

In an old side project, an application that suggests meals based on calorie input, with AngularJS for the frontend I had been using the ng-style directive to set the CSS styles in the template.

The controller looked like this:


(function() {
  angular
    .module('foodApp')
    .controller('calorieCtrl', calorieCtrl);

  function calorieCtrl() {
    var vm = this;

    vm.styleCalorieInput = {
      "background-color": "#3cb9c6",      
      "border-color": "transparent",      
      "border-radius": "10px"
    };

    vm.styleError = {
      "color": "#f3c4a3"
    };
    ...
}();

Here I am using the controllerAs syntax to create a view model I can bind my data to so I can access it in the template like so:

...
<div class="well" ng-style="vm.styleCalorieInput">
  <span ng-style="vm.styleError">...</span>
</div>
...

Even though this approach works I didn't like that I was setting the styles in the component, I wanted to define a separate stylesheet for each component like I can with Angular and still define stylesheets for the entire application in a single file if I wanted to.

I found angular-route-styles that allows me to declare route-specific styles using the $routeProvider service and it solves my problem perfectly.

I used it by copying route-styles.js into my lib folder and included the file in index.html like so:


<!DOCTYPE html>
<html ng-app="foodApp">
...
  <body ng-view>
    <script src="/lib/route-styles.js"></script>
    ...
  </body>
</html>

Now we need to add routeStyles as a module dependency to app.js and add the css property and value (where to find the css file(s)) to the when route definition.

(function() {
  // Adds `routeStyles` along with `ngRoute` dependency
  angular.module('foodApp', ['ngRoute', 'routeStyles']);

  function config($routeProvider) {
    $routeProvider
      .when('', {
        templateUrl: '/calorie/calorie.view.html',
        controller: 'calorieCtrl',
        controllerAs: 'vm',
        css: '/calorie/calorie.css'
      })
      .otherwise({ redirectTo: '/' });
  }

   angular
    .module('foodApp')
    .config(['$routeProvider', config]);

})();

Now I could delete all the style data bindings from the controller and the ng-style directives from the view. The controller now looks like this with the deleted part commented out:

// calorie/calorie.js

(function() {
  angular
    .module('foodApp')
    .controller('calorieCtrl', calorieCtrl);

  function calorieCtrl() {
    var vm = this;

    /**
    vm.styleCalorieInput = {
      "background-color": "#3cb9c6",      
      "border-color": "transparent",      
      "border-radius": "10px"
    };

    vm.styleError = {
      "color": "#f3c4a3"
    }; 
    */
    ...
}();

And in the view, I changed the ng-style directives to classes with similar names (there are better ways to do this):

...
<div class="well styleCalorieInput">
  <span class="styleError">...</span>
</div>
...

And moved the CSS properties to a newly created calorie.css file in the same folder:

.styleCalorieInput {
  background-color: #3cb9c6;
  border-color: transparent;
  border-radius: 10px;
}

styleError {
   color: #f3c4a3;
}

If you're curious, you can read more about how Tennisgent implemented his solution here on StackOverflow.

Sentry image

Hands-on debugging session: instrument, monitor, and fix

Join Lazar for a hands-on session where you’ll build it, break it, debug it, and fix it. You’ll set up Sentry, track errors, use Session Replay and Tracing, and leverage some good ol’ AI to find and fix issues fast.

RSVP here →

Top comments (0)

Image of Datadog

The Essential Toolkit for Front-end Developers

Take a user-centric approach to front-end monitoring that evolves alongside increasingly complex frameworks and single-page applications.

Get The Kit

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay