The Road to Angular 2.0 part 4: Components

Intro


I gave a presentation at the GOTO conference in Amsterdam titled: The Road to Angular 2.0. In this presentation, I walked the Road to Angular 2.0 to figure out why Angular 2.0 was so different from 1.x.

This series of blogposts is a follow up to that presentation.

theroadtoangular5

Components


Last week we took a look at TypeScript and how it is going to improve our productivity. That combined with the posts about the new template syntax and the post about ES6, gives us a good perspective on how our Angular 2.0 is going to be written.

This week’s post is about Components, and unlike the previous weeks topics, components changes the way we think about our Angular 2.0 applications, not just how we write Angular.

Lets start by looking what a component actually is.



What is a component?


A component in Angular is defined as a class which has both a Controller and a View. In Angular 2.0 your entire application will consist of Components that work together and build on top of each other.

Officially an Angular 2.0 component is called a "Component Directive" but we will use the term "Component" because it is used more often.

This is what a component looks like:
import {Component, View} from 'angular2/angular2';

@Component({
  selector: 'person'
})
@View({
  template: `My name: {{ name }}`
})
class PersonComponent {
  name: string;
  friends: Array;

  constructor(name: string) {
    this.name = name;
  }
}

Surprise! You have already seen a complete component in last weeks post about Types. A component is a Controller and View wrapped in a class, so what are the Controller and View in the example above? The answer is that @View is, perhaps unsurprisingly, the View. The Controller is the instance of the PersonComponent, with all properties and methods that go with it.

A component also has a @Component annotation. This basically means that a class which has the @View and @Component annotations is a Component.

Input / Output


A property of a component is very clearly defined in terms of input and output.
This means that every piece of input and output must be explicitly defined. This means that if a component requires a directive, that you must explicitly state so, and provide that directive. If the component has a specific event, you want the rest of the world to know of, you must explicitly declare that event. Here is how I visualize a component:
Angular-component

Let's define what Input and Output mean in the context of Components.

Input


Lets say we have component which uses the NgIf directive inside of its template:
import {View, NgIf} from 'angular2/angular2';

@View({
  template: `My name: {{ name }}`, 
  directives: [NgIf] 
})

In order for the NgIf to work we must first import NgIf from angular2 itself. Then we must explicitly declare that the @View uses the NgIf directive by adding it to the "directives" property on the @View annotation.

Another example is if we have a component which has a property that can be bound to inside of a template. For example: a "name" property on the person component, in order for this to work:
<person [name]="firstName"></person>

We must declare our component like this:
import {Component} from 'angular2/angular2';

@Component({
  selector: 'person',
  properties: { name: 'name' }
})

So in order for the component to have a HTML property we must define it explicitly before hand inside of the "properties" object.

Output


The output of a component, like input, must be explicitly defined as well. For example if we give our PersonComponent an "upvote" event which can be used like this:
<person (upvote)="vote()"></person>

We must declare our component like this:
import {Component} from 'angular2/angular2';

@Component({
  selector: 'person',
  events: ['upvote'}
})

We must add the "upvote" event to the array of "events" within the @Component.

Benefits of Components


What are the benefits of components as Angular 2.0 describes them?

The first benefit is that components are easy to reason with, this is because components are so strictly defined in terms of inputs and outputs. Just by reading the definition of a component it becomes clear what it dependencies are and what events you can subscribe to.

Having clearly defined components is also great for your text editor and IDE. They can read the definition of your component, and provide you with better autocompletion. But I can also imagine tooling which will analyse your project and tell you which built-in directives you use. In fact the tooling could use that information to strip Angular 2.0 down to the bare core that your application needs.

Another property that makes components great is that they are composable. You can view components as lego blocks from which you can build more complex things, such as houses, and from houses you can then make an entire city, and so on. Imagine a trashcan button with an "are you sure" message, you can use that throughout many components in your application.

Components can also be reused quite easily, because they are isolated. For example the trashcan button, it can easily be copied from project A to another project B. Figuring out what the dependencies of the trashcan button are is as simple as looking at its definition.

Origin Story


Every hero needs a good origin story. The origin of the Component Directive lies in two APIs from Angular 1.x: the directive API and the Controller API. These two APIs had some overlapping use cases:
Directive-controller-overlap


Many of the user cases for the controller you could implement with directives instead, the inverse is also true, many of the user cases for a directive you could implement with a controller. If you have ever taught Angular 1.x to someone you will often get the question: How do I decide when to use a controller or a directive? This question is very difficult to answer.

But as it turns out the developers of Angular 1.x really wanted us to use directives a lot more than they wanted us to use controllers. I think that the reason people gravitate to controllers is that most of us come from a traditional MVC background such as Spring MVC or Rails. This makes you are naturally inclined to use "controllers", since that is what you know best.

So to solve the problem of having two competing APIs and to guide people to using directives, they merged the two APIs into one API to rule them all: the Component Directive.

When you hear that the controller and directive APIs are dead, you now know that they live on in their love child: the Component Directive.

Conclusion


Components give us a fundamental new way to build Angular applications, in a composable and reusable way. Components will be the bread and butter of Angular 2.0 applications.

Next week we will look at "bindings" in Angular 2.0: how multiple components team up to form Angular 2.0 applications, and how information and events flow between components. Then you will understand why angular 2.0 is 3x to 10x faster than an Angular 1.x application!