Thursday, 31 December, 2015 UTC


Summary

Components are the molecules of Angular 2 applications, and we are going to spend a few minutes introducing this new building block. We are going to assume a basic familiarity with Angular 1 and the fundamental mechanisms of the framework. And now time for a brief history lesson!

A Brief History of Angular 1.X Views and Controller

In Angular 1, the prevalent theme was a controller and template pair. As the novelty of sample applications wore off, there was a natural evolution of how views and controllers were approached within an Angular application. People wanted to build complicated things that solved hard problems.

Sample Application Scenario

The initial approach was to build out an HTML template and drop in a controller via ngController. This approach worked as long as we were doing sample applications and to-do lists. Small and limited functionality resulted in a small controller that was easy enough to manage.

Sample Application Meets the Real World Scenario

As our application grew, so did our controller. This eventually became unwieldy, and we needed to find a better way to divide our application up into smaller pieces. There are two dominant approaches to this problem, and each has their own merits. You could break your app up into template-controller pairs with named routes using ui-router, which essentially turned your application into a state machine. Or, you could divide your interface up into self-contained directives that encapsulated the template-controller pair.

Named Routes Scenario

Named routes give us the ability to create containers in our interface that we can target with specific template-controller pairs. If we wanted to render sidebar-specific functionality within our page, we could add a div element with the attribute directive ui-view=”sidebar” which would hold our sidebar view as seen in the state definition table below.
$stateProvider
  .state('home',{
    views: {
      'sidebar': {
        templateUrl: 'sidebar.html',
        controller: 'SidebarCtrl',
        controllerAs: 'sidebarCtrl'
      },
      'content': {
        templateUrl: 'content.html',
        controller: 'ContentCtrl',
        controllerAs: 'contentCtrl'
      },
      'footer': {
        templateUrl: 'footer.html',
        controller: 'FooterCtrl',
        controllerAs: 'footerCtrl'
      }
    }
  });
Our HTML may look something like this.
<div ui-view="sidebar"></div>
<div ui-view="content"></div>
<div ui-view="footer"></div>
When we need to add an additional feature into our application, we can accomplish this by adding in another named ui-view element and then augmenting our states to include the a new template-controller pair. Leveraging ui-router to create fine-grained management of your application is a solid choice and has been executed in numerous large-scale applications. The drawback to this is that your template-controller pair is tied to the state definition table and what happens when you want to reuse that pair in multiple places? What happens if you want to share it across applications?

Directives Scenario

Portability is one of the main reasons for architecting your application using directives. Hand in hand with portability is the ease in which you can compose your application with well-designed directives.
If you compare the three directives that are defined below with the state definition table above, you will notice that they are quite similar. The dressing is slightly different, but the same template-controller pairs are immediately evident.
angular.module('MyApp',[])
  .directive('footer', function() {
    return {
      templateUrl: 'sidebar.html',
      controller: SidebarCtrl,
      controllerAs: 'sidebarCtrl'
    }
  })
  .directive('content', function() {
    return {
      templateUrl: 'content.html',
      controller: ContentCtrl,
      controllerAs: 'contentCtrl'
    }
  })
  .directive('footer', function() {
    return {
      templateUrl: 'footer.html',
      controller: FooterCtrl,
      controllerAs: 'footerCtrl'
    }
  });
Our HTML would also look quite similar.
<div sidebar></div>
<div content></div>
<div footer></div>
And if we were restricting element tags.
<sidebar></sidebar>
<content></content>
<footer></footer>
By treating our directives as standalone elements, we have created a perfect segue into Angular 2 components.

Enter Angular 2 Components

Angular 2 expands on this concept of standalone template-controller pairs through the introduction of components. On the surface, the overall pattern is the same, but the execution has been greatly simplified. I am a huge fan of ui-router but it took me a while to wrap my mind around the nuances of nested state. I still find myself getting fuzzy depending on the complexity of the application. We could also dedicate an entire episode of ngWat to directives and its cray cray API. The Angular team did an excellent job of distilling the best practices from Angular 1 while avoiding most of the cognitive overhead and as a result, Angular 2 components are so much simpler!
What served as a controller in Angular 1 is now just an ES2015 class. Anyone who is familiar with a classical language can look at the code below and have a pretty good shot at reasoning it out.
export class HomeComponent {
  // set our default properties values
  title = 'Home Page';
  body = 'This is the about home body';
  message = '';
  // inject StateService using TypeScript private modifier 
  constructor(private _StateService: StateService) { }

  ngOnInit() {
    this.message = this._StateService.getMessage();
  }

  updateMessage(m: string): void {
    this._StateService.setMessage(m);
  }
}
We have a constructor, properties, and methods wrapped up in an ES2015 class that will be familiar to developers coming from a classical language background. Because we are using TypeScript, we get some extra sugar in the form of types with public and private members. For most developers, this is Intro to Programming 101 stuff but it is still a much better alternative to the Ph.D. we had to get to work with directives.
We have our “controller” but how does our template come into play? Angular 2 uses the concept of metadata to take a standard ES2015 class and decorate it with extra information that tells our Angular application how to run. We are going to decorate our class with a @Component definition that tells Angular what HTML selector to target and what templateUrl to use in the process.
@Component({
  selector: 'home',
  templateUrl: 'app/home/home.component.html'
})
There are more options that we can define, but I have kept it concise to draw out the template-controller theme. The entire combination looks like this.
@Component({
  selector: 'home',
  templateUrl: 'app/home/home.component.html'
})
export class HomeComponent {
  // set our default properties values
  title = 'Home Page';
  body = 'This is the about home body';
  message = '';
  // inject StateService using TypeScript private modifier 
  constructor(private _StateService: StateService) { }

  ngOnInit() {
    this.message = this._StateService.getMessage();
  }

  updateMessage(m: string): void {
    this._StateService.setMessage(m);
  }
}
We have just brought our template-controller pair from the paleolithic age into a brave new world. Angular 2 components give us a concise way to express a better composable architecture regarding power and simplicity. The fact that Angular 2 components eschew proprietary and somewhat esoteric APIs for native JavaScript features is an enormous step in the right direction.

Angular 2 Component Example

 
A picture is worth a thousand words but a video is worth ten thousand. In the lesson above, I am going to walk through an exercise that we commonly use at AngularClass when talking about Angular architecture. I really like this exercise because it covers a lot of concepts in the context of a working application that is fairly easy to figure out. For instance, you will also see the module folder pattern which is a best practice carry over from Angular 1.
Download the sample project at this link https://github.com/simpulton/angular2-website-routes and let’s get started!
We are going to be focusing on components in this lesson but if you want to learn more about the sample application, you can read about it in this post Get Started with Angular 2 by Building a Simple Website

Resources

Sample Project
Component Documentation
Template Documentation
Router Documentation
Angular 2 for AngularJS developers
The post Angular 2 Components for AngularJS Developers appeared first on AngularClass.