Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Getting Started with Angular - Second edition - Second Edition

You're reading from  Getting Started with Angular - Second edition - Second Edition

Product type Book
Published in Feb 2017
Publisher Packt
ISBN-13 9781787125278
Pages 278 pages
Edition 2nd Edition
Languages
Author (1):
Minko Gechev Minko Gechev
Profile icon Minko Gechev

Table of Contents (16) Chapters

Getting Started with Angular Second Edition
Credits
Foreword
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface
1. Get Going with Angular 2. The Building Blocks of an Angular Application 3. TypeScript Crash Course 4. Getting Started with Angular Components and Directives 5. Dependency Injection in Angular 6. Working with the Angular Router and Forms 7. Explaining Pipes and Communicating with RESTful Services 8. Tooling and Development Experience

Chapter 4. Getting Started with Angular Components and Directives

By this point, we're already familiar with the core building blocks that Angular provides for the development of single-page applications and the relations between them. However, we've touched only the surface by introducing the general idea behind Angular's concepts and the basic syntax used for their definition. In this chapter, we'll take a deep dive into Angular's components and directives.

In the following sections, we will cover these topics:

  • Enforced separation of concerns of the building blocks that Angular provides for developing applications.

  • The appropriate use of directives or components when interacting with the DOM.

  • Built-in directives and developing custom ones.

  • An in-depth look at components and their templates.

  • Content projection.

  • View children versus content children.

  • The component's life cycle.

  • Using template references.

  • Configuring Angular's change detection.

The "Hello world!" application in Angular


Now, let's build our first "Hello world!" application in Angular. In order to get everything up and running as easy and quickly as possible, for our first application, we will use the ECMAScript 5 syntax with the transpiled bundle of Angular. First, create the index.html file with the following content:

<!-- ch4/es5/hello-world/index.html --> 
 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  <script src="https://unpkg.com/zone.js@0.6.25/dist/zone.js"></script>
  <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
  <script src="https://unpkg.com/rxjs@5.0.1/bundles/Rx.js"></script>
  <script src="https://unpkg.com/@angular/core@2.2.0/bundles/core.umd.js"></script>
  <script src="https://unpkg.com/@angular...

Using TypeScript


Although we already have an Angular application running, we can do much better! We didn't use any package manager or module loader. We spent all of Chapter 3, TypeScript Crash Course, talking about TypeScript; however, we didn't write a single line of it in the preceding application. Although it is not required that you use TypeScript with Angular, it's more convenient to take advantage of all the bonuses that static typing provides. By using TypeScript, we can also use the Ahead-of-Time compilation in Angular.

Setting up our environment

The core team of Angular developed a brand new CLI tool for Angular, which allows us to bootstrap our applications with a few commands. Although we will introduce it in the final chapter, by then, in order to boost our learning experience, we will use the code located at https://github.com/mgechev/getting-started-with-angular. This repository includes all the examples in this book, in one big application. It has all the required dependencies...

Playing with Angular and TypeScript


Now, let's play around with the files we already have. Navigate to the app/ch4/ts/hello-world directory inside getting-started-with-angular. Then, open app.ts and replace its content with the following snippet:

// ch4/ts/hello-world/app.ts 
 
import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

@Component({
  selector: 'my-app',
  templateUrl: './app.html'
})
class App {
  target: string;
  constructor() {
    this.target = 'world';
  }
}

@NgModule({
  declarations: [App],
  imports: [BrowserModule],
  bootstrap: [App],
})
class AppModule {}

platformBrowserDynamic().bootstrapModule(AppModule);

Let's take a look at the code line by line:

import {Component, NgModule} from '@angular/core';
import {BrowserModule...

Using Angular directives


We have already built our simple "Hello world!" app. Now, let's start building something that is closer to a real-life application. By the end of this section, we'll have a simple application that lists a number of items we need to do and greets us at the header of the page.

Let's start by developing our app component. The two modifications from the preceding example that we need to make are renaming the target property to name and adding a list of todos to the component's controller definition:

// ch4/ts/ng-for/detailed-syntax/app.ts 
 
import {Component, NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

@Component({
  selector: 'app',
  templateUrl: './app.html',
})
class App {
  todos: string[];
  name: string;
  constructor() {
    this.name = 'John';
    this.todos = ['Buy milk...

Improved semantics of the directives syntax


In Chapter 1, Get Going with Angular, we mentioned the opportunity for improved tooling in Angular. A big issue in AngularJS is the different ways in which we can use directives. This requires an understanding of the attribute values, which can be literals, expressions, callbacks, or a microsyntax. Starting with Angular 2, this problem is eliminated by introducing a few simple conventions that are built into the framework:

  • propertyName="value"

  • [propertyName]="expression"

  • (eventName)="handler()"

In the first line, the propertyName attribute accepts a string literal as a value. Angular will not process the attribute's value any further; it will use it the way it is set in the template.

The second syntax, [propertyName]="expression", gives a hint to Angular that the value of the attributes should be handled as an expression. When Angular finds an attribute surrounded by brackets, it will interpret the expression in the context of the component associated...

Defining Angular directives


Now that we've built a simple Angular component, let's continue our journey by understanding the Angular directives.

Using Angular directives, we can apply different behavioral or structural changes over the DOM. In this example, we will build a simple tooltip directive.

In contrast to components, directives do not have views and templates. Another core difference between these two concepts is that the given HTML element may have only a single component but multiple directives on it. In other words, directives augment the elements compared to components that are the actual elements in our views.

Angular's official style guide's recommendation is to use directives as attributes, prefixed with a namespace. Keeping this in mind, we will use the tooltip directive in the following way:

<div saTooltip="Hello world!"></div> 

In the preceding snippet, we use the tooltip directive over the div element. As a namespace, its selector uses the sa string.

Note

Since...

Creating custom Angular components


Now, let's build a simple to-do application in order to demonstrate the syntax to define components further.

Our to-do items will have the following format:

interface Todo { 
  completed: boolean; 
  label: string; 
} 

Let's start by importing everything we will need:

import {Component, NgModule, ViewEncapsulation} from '@angular/core'; 
//...

Now, let's declare the component and the metadata associated with it:

@Component({ 
  selector: 'todo-app', 
  templateUrl: './app.html', 
  styles: [ 
    `ul li { 
      list-style: none; 
    } 
    .completed { 
      text-decoration: line-through; 
    }` 
  ], 
  encapsulation: ViewEncapsulation.Emulated 
}) 

Here, we specify that the selector of the Todo component will be the todo-app element. Later, we add the template URL, which points to the app.html file. After that, we use the styles property; this is the first time...

Explaining Angular's content projection


Content projection is an important concept when developing user interfaces. It allows us to project pieces of content into different places of the user interface of our application. Web Components solve this problem with the content element. In AngularJS, it is implemented with the infamous transclusion.

Angular is inspired by modern Web standards, especially Web Components, which led to the adoption of some of the methods of content projection used there. In this section, we'll look at them in the context of Angular using the ng-content directive.

Basic content projection in Angular

Let's suppose we're building a component called fancy-button. This component will use the standard HTML button element and add some extra behavior to it. Here is the definition of the fancy-button component:

@Component({ 
  selector: 'fancy-button', 
  template: '<button>Click me</button>' 
}) 
class FancyButton { ... } 

Inside of the ...

Hooking into the component's life cycle


Components in Angular have a well-defined life cycle, which allows us to hook into different phases of it and have further control over our application. We can do this by implementing specific methods in the component's controller. In order to be more explicit, thanks to the expressiveness of TypeScript, we can implement different interfaces associated with the life cycle's phases. Each of these interfaces has a single method, which is associated with the phase itself.

Although code written with explicit interface implementation will have better semantics, since Angular supports ES5 as well, within the component we can simply define methods with the same names as the life cycle hooks (but this time, prefixed with ng) and take advantage of duck typing.

The following diagram shows all the phases we can hook into:

Figure 10

Let's take a look at the different life cycle hooks:

  • OnChanges: This hook will be invoked once a change in the input properties of...

Defining generic views with TemplateRef


We are already familiar with the concepts of inputs, content children, and view children, and we also know when we can get a reference to them in the component's life cycle. Now, we will combine them and introduce a new concept-TemplateRef.

Let's take a step back and take a look at the last to-do application we developed earlier in this chapter. In the following screenshot, you can see what its UI looks like:

Figure 11

If we take a look at its implementation in ch4/ts/inputs-outputs/app.ts, we'll see that the template used to render the individual to-do items is defined inside the template of the entire to-do application.

What if we want to use a different layout to render the to-do items? We can do this by creating another component called Todo, which encapsulates the responsibility of rendering them. Then, we can define separate Todo components for the different layouts we want to support. This way, we need to have n different components for n different...

Understanding and enhancing the change detection


We have already briefly described the change detection mechanism of the framework. We said that compared to AngularJS, where it runs in the context of the "scope", in Angular 2 and later versions, it runs in the context of the individual components. Another concept we mentioned is the zones, which basically intercept all the asynchronous calls that we make using the browser APIs and provide execution context for the change detection mechanism of the framework. Zones fix the annoying problem that we have in AngularJS, where when we use APIs outside of Angular, we needed to explicitly invoke the digest loop.

In Chapter 1, Get Going with Angular and Chapter 2, The Building Blocks of an Angular Application, we discussed that the code that performs change detection over our components is being generated, either runtime (Just-in-Time) or as part of our build process (Ahead-of-Time). AoT compilation works great for environments with strict CSP (Content...

Summary


In this chapter, we went through the core building blocks of an Angular application: directives and components. We built a couple of sample components, which showed us the syntax to be used for the definition of these fundamental concepts. We also described the life cycle of each directive and the core set of features the given directive and component have. As the next step, we saw how we can enhance the performance of our application using the OnPush change detection strategy with an immutable data.

The next chapter is completely dedicated to the Angular services and the dependency injection mechanism of the framework. We will take a look at how we can define and instantiate custom injectors and how we can take advantage of the dependency injection mechanism in our directives and components.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Getting Started with Angular - Second edition - Second Edition
Published in: Feb 2017 Publisher: Packt ISBN-13: 9781787125278
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}