Angular UI Routing and Components
- Routing to a component became a desired behavior.
- Angular UI Router has slowly been integrating support for routing to Angular components.
- The sole purpose of the smart component is to make a service call and properly bind to the dumb component.
- Create a smart component that wraps a dumb component.
- With that came the realization that a webpage is a component comprised of components.
Angular UI Router has slowly been integrating support for routing to Angularcomponents. This post will discuss why that’s useful, and how to do it using both…
@aviture: Interested in using the new @angularjs components with UI Router? Check out the latest from @evan_williams at .
Angular UI Router has slowly been integrating support for routing to Angular components. This post will discuss why that’s useful, and how to do it using both Angular UI Router 0.x.x and 1.0.0-beta.x versions.
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, among other things.
This allowed for better componentization of entire views and applications. With that came the realization that a webpage is a component comprised of components.
Thus, routing to a component became a desired behavior.
Before delving into the use of UI Router to route to components, the concept of smart and dumb components should be discussed.
A smart component is one that is very aware of the API and the data driving a view. This means in its controller, it’s typically making a service call upon initialization of the component. It knows what is required to make the call and the response it should expect from the API.
On the other hand, there are dumb components which know what to do with a passed in object or value and what interactions it is responsible for. It typically does not interact with any services. Most interactions result in a callback to a parent component to pass information back up to be used by a smart component or are related purely to display changes.
For the sake of reusability, dumb components typically are the most reusable (think containers with headers, navigation bars, select boxes, etc). Smart components are great for building full applications from a high level, but they aren’t very customizable.
The best way to make a component dumb is to remove the API calls from the controllers and find a way of providing that data via some sort of binding. This is helpful if you already have the same data that a smart component needs, but don’t want to make two hits to the server for it.
This is a concept that has a bigger scope than just that of Angular. This article by Dan Abramov about Smart vs. Dumb components (what the author calls Presentational vs Container components) goes further in depth into this pattern, but in React.
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.
The best way to write an application as a component is to take advantage of nested views in UI Router. This can be challenging, at times, but it allows for great flexibility in swapping out components based on the state of the application.
The first integration with routable components was to, instead of using a templateUrl property on the state definition, use the template property instead. An example of this would be as follows:
Obviously, this works, but when each and every state is declared with an HTML element that is simply a single HTML element with no attributes, it starts getting tedious.
in a navigation template, you can now do that without having to generate a new component from a template had you set up the same state as such:
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?
One possible answer to this is to resolve the data necessary for the component to function from the route and then bind it into the component via the component’s bindings. There are two approaches to doing this:
There are some obvious tradeoffs to both options. With a smart component wrapper, you’ve got an additional component to maintain. For resolving to the component using UI router, you’re tying yourself to the router’s ability, and it’s also more difficult to manage exception handling.
That being said, creating routable components via UI Router’s bindings is extremely simple, and UI Router is powerful enough and provides great functionality to the point where, if it’s in your project, it’ll likely remain there until a full rewrite of an application.
property of the state definition.
component. For those smart components that simply make a service call then display the information, we can actually eliminate an entire controller, as well.
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.
declaration, and not dasherized.
definition. This streamlines the definition:
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.
To see an example of the above concepts, please check out this github repo.