Telerik blogs
angular_boilerplate_header

Angular 2 is nearing release candidate. I'm excited, and so are many others. Last week we spoke to Brad Green on our podcast where he uncovered some exciting aspects of Angular 2, as well as the future plans he has for building out awesome new features.

As we approach the first finish line for the release candidate, it's time to start digging into the future of Angular. First up, Angular 2 is an entire rewrite of the first version that we know and love, usually referred to as "AngularJS". There are common concepts between the two, however the architecture differs somewhat, as well as the way we write Angular code.

We're going to build a really simple boilerplate, without compilers, tooling or other complexities and focus on fully understanding the architecture process behind setting up Angular 2 with components, TypeScript and routing. The source code will be available at the end!

Component Theory

To get absolutely anywhere with Angular 2, we need to first learn how to set it up for rendering components. Angular is all about components and component architecture - so essentially everything is a component, made up of other components!

This means we need a root component to serve as our application base, and then each other component we create will be some sort of child component thereafter.

Application structure

We'll have a main file, called main.ts, which will take care of the bootstrapping and root component import. Each "view" we create will have it's own file, such as home.component.ts, which is just a root component for the home view. This will then get hooked up to our router in which we can tell Angular where to display particular views. So let's dig into the first step of setting up the HTML, importing the right libraries and then bootstrapping the application.

HTML setup

We'll begin with an empty shell, and slowly assemble the bits we need. Here we have a basic HTML page:

<!doctype html>
<html>
  <head>
    <title>Superfast Angular 2 setup</title>
    <base href="/">
    <link rel="stylesheet" href="css/style.css">
  </head>
  <body>

  </body>
</html>

Next up, we'll add the library dependencies we need from Angular 2 - note how we're already including router.dev.js, which we'll use later in this article! It's an external module, so let's add it after Angular 2.

<script src="/libs/angular2-polyfills.js"></script>
<script src="/libs/system.js"></script>
<script src="/libs/typescript.js"></script>
<script src="/libs/Rx.js"></script>
<script src="/libs/angular2.dev.js"></script>
<script src="/libs/router.dev.js"></script>

The second dependency we've added is system.js, which is a module loader. We'll instruct it to tell Angular where our app is and to transpile our TypeScript:

<script>
System.config({
  transpiler: 'typescript',
  typescriptOptions: {
    emitDecoratorMetadata: true
  },
  map: {
    app: './js'
  },
  packages: {
    app: {
      main: './main.ts',
      defaultExtension: 'ts'
    }
  }
});
System
  .import('app')
  .catch(console.error.bind(console));
</script>

Transpiling here will happen in the browser using typescript.js, which makes it so easy to get started without having to run local development servers and compiler tasks. For production we'll obviously want to drop typescript.js and compile things locally, but for our simple getting-started project, it's perfect!

What we're doing is setting up system.js and pointing it to our app using map: {} and referencing our './js' directory. We then define the default extension (i.e. .ts) for TypeScript. Then, finally, we're calling System.import() to dynamically fetch our application assets required to bootstrap our app. You can dive more into System.js here.

Bootstrapping

The bootstrap phase of an Angular 2 application is where we need to kickstart our app. We've already mentioned we're going to be using main.ts for this, so let's add some code and walk through it:

import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent);

For all Angular 2 development, we're going to be using TypeScript, which means we get to use ES2015 import syntax. We need to import the bootstrap method using Object destructuring from 'angular2/platform/browser'. This makes it available within the file for calling as a function. On the second line, we add our AppComponent import, which we still need to create, so let's get going with that!

Root App Component

Our root Component serves as the absolute base, and you could consider it to be "common" code shared across the entire application. For instance, it might contain a header with a logo, and possible sidebar with an area inside for managing views.

First we need to import Component from the Angular 2 core, and setup our class decorator with relevant metadata.

// app.component.ts
import {Component} from 'angular2/core';

@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      Hello world!
      <main>
        <!-- stuff -->
      </main>
    </div>
  `
})
export class AppComponent {

}

The selector property in the @Component decorator refers to the custom element we're going to need to create in our index.html file. So let's jump over there and add the relevant tag:

<body>
  <my-app>
    Loading...
  </my-app>
</body>

We've added some text in the middle, Loading.... This gets displayed while the application is fetching the necessary assets. You could completely customize this contents with a unique loading bar or anything you like, and it'll be replaced once Angular 2 is fully compiled and ready!

So far we've got the base of our app, with a single component. Ideally, we should now setup some Views and tie them into particular routes via the Component Router.

Views

With our bootstrap in order and root component rendered, it's time to setup what we'd consider a view. A view is simply another component, but more of a high level one.

Let's setup two views. Down the road, we create and import further components into our view, but, for purposes of this article and basic boilerplate, we're simply going to be using high level view components and setting up routing.

Inside our app.component.ts, let's add some imports for two views:

// app.component.ts
import {Home} from './home/home.component.ts';
import {Login} from './login/login.component.ts';

We're creating two basic views here that are just Angular 2 components. Now that we're referencing them, let's create the files starting with our Home View Component:

// home/home.component.ts
import {Component} from 'angular2/core';

@Component({
  selector: 'home',
  template: `
    <h1>Home view!</h1>
  `
})
export class Home {
  constructor() {

  }
}

Then the Login view component:

/login/login.component.ts
import {Component} from 'angular2/core';

@Component({
  selector: 'login',
  template: `
    <h1>Login view!</h1>
  `
})
export class Login {
  constructor() {

  }
}

These are pretty much identical components, simply displaying a differnet view name inside an <h1> tag. Now taht we've got two views, we need to head back to main.ts and hook them up to the Component Router.

Routing

Angular 2's component router is a simple decorator for a component class. Before we can use it, we need to import the ROUTER_PROVIDERS into our main.ts file and pass it into our bootstrap method as a custom provider. The bootstrap method takes an array of values:

// main.ts
import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';
import {ROUTER_PROVIDERS} from 'angular2/router';

bootstrap(AppComponent, [
  ROUTER_PROVIDERS
]);

Now the providers are added, we can then start using the router! Let's dive back to app.component.ts and setup our router!

First, we need to import the router, namely the RouteConfig from the external angular2/router module:

// app.component.ts
...
import {RouteConfig} from 'angular2/router';

Next, we need to call the RouteConfig function. However, it's a decorator, so we need to decorate the AppComponent class with it:

// app.component.ts
@RouteConfig([
  { path: '/', name: 'Home', component: Home, useAsDefault: true },
  { path: '/login', name: 'Login', component: Login }
])
export class AppComponent {

}

The above configuration defines the URL using path. The name of the Component allows us to alias the route so that we can dynamically link to the state inside our templates. The component property allows us to assign our Home or Login views respectively.

Let's take a look at what we've got so far inside app.component.ts:

// app.component.ts
import {Component} from 'angular2/core';
import {RouteConfig} from 'angular2/router';
import {Home} from './home/home.component.ts';
import {Login} from './login/login.component.ts';

@Component({
  selector: 'my-app',
  template: `
    <div class="app">
      Hello world!
      <main>
        <!-- stuff -->
      </main>
    </div>
  `
})
@RouteConfig([
  { path: '/', name: 'Home', component: Home, useAsDefault: true },
  { path: '/login', name: 'Login', component: Login }
])
export class AppComponent {

}

Looking good! So we've completed the first step of telling Angular 2 what routes to setup, however we haven't declared where our views will be dynamically rendered. We also have not created any sort of navigation between views with links.

Up top, we need to include ROUTER_DIRECTIVES. We can add it in nicely alongside RouteConfig:

// app.component.ts
import {RouteConfig, ROUTER_DIRECTIVES} from 'angular2/router';

To be able to use ROUTER_DIRECTIVES, we need to pass it into our component!

// app.component.ts
@Component({
  selector: 'my-app',
  directives: [ROUTER_DIRECTIVES]
  template: `
    <div class="app">
      Hello world!
      <main>
        <!-- stuff -->
      </main>
    </div>
  `
})

Now that the directives from the component router module are available, we can specify where we want our views to be rendered. In Angular 2, these are called "route outlets." There's a <router-outlet> directive that we can use where we want these views to be rendered:

// app.component.ts
@Component({
  selector: 'my-app',
  directives: [ROUTER_DIRECTIVES]
  template: `
    <div class="app">
      Hello world!
      <main>
        <router-outlet></router-outlet>
      </main>
    </div>
  `
})

Angular will render our page out with the initial view as /, mount the component Home and render out <h1>Home view!</h1> inside our container. This is super!

So now we need to be able to let users navigate around our app using the routerLink property bindings. These bindings are also part of the ROUTER_DIRECTIVES and provide dynamic navigation based off the route name property:

// app.component.ts
@Component({
  selector: 'my-app',
  directives: [ROUTER_DIRECTIVES]
  template: `
    <div class="app">
      Hello world!
      <nav>
        <ul>
          <li>
            <a [routerLink]=" ['Home'] ">Home</a>
          </li>
          <li>
            <a [routerLink]=" ['Login'] ">Login</a>
          </li>
        </ul>
      </nav>
      <main>
        <router-outlet></router-outlet>
      </main>
    </div>
  `
})

We can pass in an array, which denotes the views associated with a routerLink. The first element in the array corresponds to a parent route, while child routes are specified as further array elements.

Conclusion

We've setup Angular 2 super fast, with some base components, routing and a bootstrap call, I've bundled this code on GitHub, you can grab it here and start playing! You will need to use a local server (of your chosing) to get it running, if you're on OSX you can simply run python -m SimpleHTTPServer or use an IDE.


todd-motto
About the Author

Todd Motto

Todd Motto (@toddmotto) is a Google Developer Expert from England, UK. He's taught millions of developers world-wide through his blogs, videos, conferences and workshops. He focuses on teaching Angular and JavaScript courses over on Ultimate Courses.

Comments

Comments are disabled in preview mode.