Angular UI Routing and Components

Background

With the introduction of Angular components in version 1.5, the concept of a stand alone, reusable set of behaviors and views became easier to define than previously done in directives. These changes include: abstracting scope, binding to controllers explicitly, providing lifecycle hooks into the controller, as well as a few other things.

Smart vs Dumb Components

Before delving into the use of UI Router to route to components, the concept of smart and dumb components should be discussed.

Writing an Application as a Component

With the move to componentized applications, there was mind shift related to how we view applications. Entire applications can be viewed as a component. This actually has practical use cases. For instance, if we write our application as a component, we can take a stand alone web application and potentially put it into a hybrid web container and make a mobile application from it.

Use of Components in State Definition using Template

The first integration with routable components was to, instead of using a templateUrl property on the state definition, was to use the template property, instead. An example of this would be as
follows:

import angular from 'angular';  
import angularUIRouter from 'angular-ui-router';
angular.module('ew', [
angularUIRouter
])
.config(($stateProvider) => {
$stateProvider.state('main', {
url: '*path',
template: '<my-component></my-component>'
});
})
.component('myComponent', {
template: '<span ng-bind="$ctrl.greeting"></span>',
controller: class {
get greeting() {
return 'Hello, world!'
}
}
});
angular.module('ew', [  
angularUIRouter
])
.config(($stateProvider) => {
$stateProvider.state('main', {
url: '*path',
template: '<span ng-bind="$ctrl.greeting"></span>',
controller: class {
get greeting() {
return 'Hello, world!'
}
}
});
})

Binding to Components

How do we write a full application as a dumb component, when many of our routes need to make service calls to display information that a user wants to view?

  1. Create a smart component that wraps a dumb component. The sole purpose of the smart component is to make a service call and properly bind to the dumb component.
  2. Use the resolve functionality provided in UI router to resolve data directly to the dumb component.

Binding to Components — 0.x.x

To bind to a component in the stable release of UI Router (0.x.x), UI Router creates a $resolve object in the context that it used to compile the contents of the ui-view.

import angular from 'angular';  
import angularUIRouter from 'angular-ui-router';
angular.module('ew', [
angularUIRouter
])
.component('user', {
bindings: {
user: '<' // Binds to the $ctrl Object
},
template: ...
})
.config(($stateProvider) => {
$stateProvider.state('main.user', {
url: '/user/:id',
template: '<user user="$resolve.user"></user>',
resolve: {
user: ($stateParams, UserService) => UserService.get($stateParams.id)
}
});
});

Binding to Components — 1.0.0-beta.x

With the release of angular-ui-router@1.0.0-beta.x, the component property was added to the state definition object. This allows for the developer to bind directly to a component as defined on the angular module. It eliminates the need for having a template containing a single element as we had seen in the past.

angular.module('ew', [  
angularUIRouter
])
.component('user', {
bindings: {
user: '<' // Binds to the $ctrl Object
},
template: ...
})
.config(($stateProvider) => {
$stateProvider.state('main.user', {
url: '/user/:id',
component: 'user',
resolve: {
user: ($stateParams, UserService) => UserService.get($stateParams.id)
}
});
});

Conclusion

To wrap things up, an application that is composed purely of components seems to be the direction the web world is going. Angular 1.5 components makes this relatively simple to achieve. In addition, it aligns with where future angular versions are going (i.e. Angular 2). Routable components in an application are very well supported in Angular UI Router both in current stable releases, as well as the beta version available on NPM.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store