Angular_2_Components_-_Nir_Kaufman by 2016

Angular_2_Components_-_Nir_Kaufman by 2016

Author:2016
Language: eng
Format: epub


}

}

Let's use data binding techniques to create a simple toggle component: @Component({

selector: 'app-root',

template: `

<h2 (click)="toggeld = !toggeld ">Click me to toggle some content1</h2> <p *ngIf="toggeld">Toggeld content</p>

`

})

export class AppComponent {}

Two-way bindings

We learned how to use one way data bindings using properties and events. Angular introduces a third option to use with input controls. This directive is called ngModel . The syntax can be a little strange, because this directive combines property and event bindings together. With ngModel , we can easily achieve two-way data binding easily. In the following example, we will bind username and password inputs to a user object: @Component({

selector: 'app-root',

template: `

<input type="text" [(ngModel)]="user.username"> <input type="password" [(ngModel)]="user.password">

<button (click)="sendUser()">Send</button> `

})

export class AppComponent {

private user = {

username: '',

password: ''

}

sendUser(){

console.log(this.user);

}

Summary

Throughout this chapter, we transform our static component to a dynamic component using core directives and data binding.

Angular 2 keeps the data binding easy, much like Angular 1. The ability to bind data to native DOM properties and events directly is a powerful feature. The core directives of Angular 2 includes only a few directives that give us some extra functionality that otherwise is hard to achieve.

Chapter 6. Component Communication Up until now, we have built a single component, but the real power of Angular components is building the interaction between them. in this chapter, we will learn how components can communicate in different ways:

Pass data from the parent component to the child through properties Define custom events on a child component for the parent to listen to Communicate via local variables

Query child components using the parent component

Passing data via properties

The parent component can pass data to the child component through properties. There are two ways that define input properties for a component:

By creating an input array on the component decorator By using the @Input decorator for decorating a class property

Using the component input array is simple and straightforward. Just declare an input array and populate it with strings that represent the name of the property you are expecting: [app.component.ts]

import { Component } from '@angular/core';

@Component({

selector: 'child-component',

inputs: ['title'],

template: `<h2>{{ title }}</h2>`

})

export class ChildComponent {}

@Component({

selector: 'app-root',

template: `

<h1>Component Interactions</h1>

<child-component [title]="title" ></child-component> `

})

export class AppComponent {

private title: string = "Sub title for child"; }

In this example, we created a child component, which defined an input array with a single string named title that represents a property that the parent component can bind to and pass data through.

Don't forget to add the ChildComponent class to the declarations attribute of the AppModule . Otherwise, this component can't be used within the template of the AppComponent . This configuration is required each time you need to use a component or a directive in another one and within the same module:

[app.module.ts]

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';

import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent, ChildComponent } from './app.component'; @NgModule({

declarations: [

AppComponent,

ChildComponent

],

imports: [

BrowserModule

],

providers: [],

bootstrap: [AppComponent]

})

export class AppModule { }

The approach of the input array is suitable when we don't need to access the input in the Component class, and we don't care about the type of the input. Alternatively, we can bind an input to a class property using the @Input() decorator: [app.component.ts]

import { Component, Input } from '@angular/core'; @Component({

selector: 'child-component',

template: `<h2>{{ title }}</h2>`

})

export class ChildComponent {

@Input() private title: string;

}

@Component({

selector: 'app-root',

template: `

<h1>Component Interactions</h1>

<child-component [title]="title"></child-component> `

})

export class AppComponent {

private title: string = 'Sub title for child'; }

Binding to a class property (the second example) is considered to be a best practice when dealing with inputs.

An input can be a primitive or an object.

Emitting custom events

When the child component needs to communicate with its parent component, it can emit an event. This technique keeps the child component de-coupled from its parent (de-coupled: doesn't need to know its parents).

In Angular, we need to use a class named EventEmitter if we want to emit events. You need to instantiate the EventEmitter class, assign it to a class property, and call the emit method.

In the following example, the child component will emit a custom event named TitleClicked when the user clicks on the title:

[app.component.ts]

import { Component, Input, EventEmitter, Output } from '@angular/core'; @Component({

selector: 'child-component',

template: `<h2 (click)="titleClicked.emit()">{{ title }}</h2>` })

export class ChildComponent {

@Input() private title: string;

@Output() private titleClicked = new EventEmitter<any>(); }

@Component({

selector: 'app-root',

template: `

<h1>Component Interactions</h1>

<child-component [title]="title"

(titleClicked)="clickHandler()"></child-component> `

})

export class AppComponent {

private title: string = 'Sub title for child'; clickHandler() {

console.log('Clicked!');

}

}

First, we imported the EventEmitter class and the Output decorator from Angular core. Then, we created a class property named titleClicked and assigned it to a fresh instance of the EventEmitter class.

Then, we bound the native click event of the <h2> element and called the emit() method of the titleClicked object.

The parent component can now bind to this event.

Referencing with a local variable

One component can access another component's properties and methods using local variables. In the following example, we create a local variable for the child component that becomes accessible within the template:

[app.component.ts]

import { Component } from '@angular/core';

@Component({

selector: 'child-component',

template: `

<h2>Content Header</h2>

<p *ngIf="flag">Toggleable Content</p>

`

})

export class ChildComponent {

private flag: boolean = false;

toggle() {

this.flag = !this.flag;

}

}

@Component({

selector : 'app-root',

template : `

<h1>Component Interactions</h1>

<button (click)="child.toggle()">Toggle Child</button> <child-component #child></child-component> `

})

export class AppComponent {}

We create a local variable using the # symbol.

The method in the child component must be public, otherwise Angular will throw an exception. This technique is very useful in some cases because it doesn't require any code inside the component class. On the other hand, the reference context is just inside the template. If you need to access the child component inside the parent component, you need to inject a reference to the child component using the @ViewChild decorator. Consider the following example:

[app.component.ts]

import { Component, ViewChild } from '@angular/core'; @Component({

selector: 'child-component',

template: `

<h2>Content Header</h2>

<p *ngIf="flag">Toggleable Content</p>

`

})

export class ChildComponent {

private flag: boolean = false;

toggle(){

this.flag = !this.flag;

}

}

@Component({

selector: 'app-root',

template: `

<h1>Component Interactions</h1>

<button (click)="toggle()">Toggle Child</button> <child-component></child-component>

`

})

export class AppComponent {

@ViewChild(ChildComponent)

private childComponent: ChildComponent;

toggle(){

this.childComponent.toggle();

}

}

The parent component is using the @ViewChild decorator (imported from angular core) passing the name of the component, and assigning it to a local class member named childComponent . If we have more than one instance of the child component, we can use the @ViewChildren decorator instead.

Querying child components with the parent component

The @ViewChildren component will provide a reference to all of the children components of a given type as a QueryList , which contains an array of child instances. Consider the following example:

[app.component.ts]

import { Component, ViewChildren, QueryList } from '@angular/core'; @Component({

selector: 'child-component',

template: `

<h2>Content Header</h2>

<p *ngIf="flag">Toggleable Content</p>

`

})

export class ChildComponent {

private flag: boolean = false;

toggle(){

this.flag = !this.flag;

}

}

@Component({

selector: 'app-root',

template: `

<h1>Component Interactions</h1>

<button (click)="toggle()">Toggle Child</button> <child-component></child-component>

<child-component></child-component>

<child-component></child-component>

`

})

export class AppComponent {

@ViewChildren(ChildComponent)

private children: QueryList<ChildComponent>; toggle(){

this.children.forEach(child => child.toggle()) }

}

Both ViewChildren and the QueryList are imported from Angular core. Summary

Components can interact and communicate in many ways. Each technique is suitable for a certain situation. The main difference is related to the scope of communication: template context or component class context.

This flexibility enables us to create complex component compositions that easily share data and interactions, which consists of APIs.

In the next chapter, we will build useful components and also learn about Angular 2 change detection and the component life cycle.

Chapter 7. Putting It All Together It's time to take everything we have learned about components and put it into practice. In this chapter, we will build useful components. We will also learn about Angular 2 change detection and the component life cycle.

The following are the topics that we will cover:

Resetting the development environment

Building a simple accordion component

Extending the accordion component tree

Extending hooking to the component life cycle events

Angular 2 Development Environment with angular-cli . We will create a new directory called components to contain all the components we will implement in this chapter. We will later create two other subdirectories in this chapter, accordion and user-info , when implementing the corresponding components:



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.