read

Part 1: Component Router Conventions



The new-angular-router coming with Angular 1.3+ now has a name: Component router.

The Component router is aptly named, as it is designed to help break your project into components (such as directives).

Here's a brief overview of some structural changes:

  • It routes to components (directives), not templates/controllers
  • The routes are setup in a controller/class, not during a config phase
  • It uses default conventions to find templates & controller names

Let's take a look at comparison between the three popular routers in Angular: ngRouter, uiRouter, & the new router.

ComponentRouterComparison

In this post, we'll look how naming using the Component router with naming conventions can help save you a lot of code.


Conventions

Conventions mean less code. But the magic behind the scenes, that is, the default template mapping and controller naming, can initially come with a lot of confusion.

Let's make a comparison with ui-router to see the repetition Component router is trying to avoid.

ui-Router Example

The popular ui-router is based on states.

  $stateProvider
      .state('abc', {
        url: '/abc',
        templateUrl: 'app/templates/abc.html',
        controller: 'AbcCtrl as vm'
      });

But not DRY enough (Don't Repeat Yourself). This method uses too much chalk.

Component Router Example

Component router comes with built in defaults of how to structure and find your code.

The router defaults assume where the template is located and what the controller will be named.

$router.config([{
      path: '/abc',
      component: 'abc'
}]);

Component router makes the following assumptions based on the component name.

  • templateUrl: '/components/abc/abc.html',
  • controller name: 'AbcController'
  • controllerAs: 'abc'

If you're using compound names, Component router uses snake-case for templates & camelCase for scripts.

$router.config([{
      path: '/defGhi',
      component: 'defGhi'
}]);
  • templateUrl: '/components/def-ghi/def-ghi.html'
  • controller name: 'DefGhiController'
  • controllerAs: 'defGhi'

To keep things easy, just organize your components in the components folder by a snake-cased name. Everybody's happy.

Not happy? If you're not going to let a router tell you how to organize your code, read on. Otherwise, you can leave it at that.

Editing Conventions

These conventions can be edited to your own liking use the $componentLoaderProvider. It's a provider, so run it in the .config() stage.


Change Controller Name

Perhaps you like to name your controllers. You can use the $componentLoaderProvider.setCtrlNameMapping function which takes the component name and returns the new default controller name.

Controller: CapitalizedCtrl

.config(function($componentLoaderProvider) {
      $componentLoaderProvider.setCtrlNameMapping(function (name) {
            // where name is the component name
            var capitalized = name.charAt(0).toUpperCase() + name.slice(1);
            return capitalized + 'Ctrl';
      });
}

The path to your templates can be changed using the $componentLoaderProvider.setTemplateMapping function which takes the component name and returns a path to the default template.

Template: states/component-name.html

.config(function($componentLoaderProvider) {
      $componentLoaderProvider.setTemplateMapping(function(name) {
            var snakeCased = name.match(/[A-Z]*[^A-Z]+/g).join('-');
            return '/states/' snakeCased + '.html';
  });
}

Conclusion

The Component router keeps your code DRY, forcing you to design your app in components, maximizing your use of directives, and using common conventions. It can be frustrating to get started with the Component Router without knowing the defaults, but personally, I've grown to appreciate it.

In part 2 we'll look into using Component router's lifecycle hooks to work some magic, as well as how to take advantage of using ES6 class inheritance.

Blog Logo

Shawn McKay

Published

Image

ShMcK

JavaScript Web Dev

Back Home