Angular Components

Components contain metadata at the top and exported classed on the bottom. Example:

@Component({
  selector: 'app-root',
  template: '<app-position></app-position>',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  private jobPosition = "CEO";
  hidePosition = false;
  getData() {
    return this.jobPosition;
  }
}

Selectors

The selector defines how a component is added to an HTML page / template. For example:

selector: ‘app-root’

The custom tags need to be shown. If a selector has dot (.) then it is referred as class:

Selector: ‘.app-root’
And square brackets refers to an attribute:
Selector: ‘[app-root]’

Templates

Using the “template” keyword means you put the markup inside it as a string

template: ‘<html…>’

But the templateUrl refers to an html file

template: ‘./template.html’

 

Styles

Make sure to include the style inside brackets as shown in the example above.

 

Interpolation

Interpolation is done through curly brackets – {{ xxx }}

The angular compiler will interpret these during run time.

<h1>{{ somevariable }}</h1>

The variables between a component and it’s template are tightly coupled and template can access anything above private variables.

You can also execute some js code inside the interpolations. But it is only read only, for example

<h1>{{ “Job: “ + jobvariable }}</h1>

Also note that inside the interpolation brackets you cannot access the global JavaScript object. For example:

{{ window.location.href }} this will error

Note that templates cannot have javascript code that accesses the JavaScript Global Object.

 

Property Binding

Angular compiler can process attributes so it’s encouraged to use these. For example

<button disabled></button>

For angular to be able to modify the attributes, put brackets around them.

<button [disabled]=’somevariable’></button>

<button bind-disabled=’somevariable’></button>

This is how angular does property binding.

 

Event Binding

Event bindings are done using the parenthesis.

<button (click)=’onclickmethod()’></button>

Event bindings can also send parameters. The $event variable is a special variable recognized by the angular compiler and it passes the event object.

<button (click)=’onclickmethod($event)’></button>

You could put the code directly in the html to have it run the code inline instead of referencing back to the component file.

 

Classes, Styles and Attributes

We can bind css classes to an html tag using the property binding syntax.

<div [class]=”myvar”></div>
...
myvar = “text-danger”

You can also bind to special keyword [ngClass] which is similar to above

<div [ngClass]=’myvar’></div>
...
myvar = { “text-danger”: false, “text-success”: true }

 

The example above will show true.

 

Finally – event binding using property binding can be for specific css property. In the example below, the text-danger css class is loaded if the result of myvar is true

<div [class.text-danger]=’myvar’></div>

When applying in-line styles, we can set a global-component level style by using the keyword “:host”. Example

styles: [`:host { color: red; }`]

Also note that styles are only applied to the current component, it doesn’t go up to parents or children. However, if you do want to apply to children under the component, use the keyword “/deep/”

 


 

Template Reference Variables

To reference elements in a template we can put a variable definition on it using hash.

<input #name placeholder="name">
<button (click)="username = name.value">Update</button>
{{ username }}

In the example above, by clicking on the update button the username variable gets set to the value of the #name input element.

 

ngIf, ngFor, ngSwitch

The expression below will not be added to the DOM during the angular compile.

<p *ngIf="false">lorem ipsum</p>

The condition can reference a variable as well instead of literal.

To do else conditions, use the “else” keyword and reference an element reference variable

<p *ngIf="false; else myblock">this will not display</p>
<ng-template #myblock>
  <p>this will be displayed instead</p>
</ng-template>

We can write complete if – then – else blocks as follows

<p *ngIf="false; then thenBlock else elseblock">this will not display</p>
<ng-template #thenblock>
 <p>this will not display</p>
</ng-template>
<ng-template #elseblock>
 <p>this will be displayed instead</p>
</ng-template>

In the example above the “thenBlock” displays only when the condition is true.

For blocks are structured as such. It can be used with or without the index elements of the loop. Also note that there special keywords like “first” and “last” that Angular uses to get the first and last elements of the array. Other keywords are “even”, “odd” etc.

<div *ngFor="let p of positions; index as i; first as f; even as e">
  <p>{{ p.title }} {{ i }} {{ f }} {{ e }}</p>
</div>

The above could display something like:

title1 0 true true
title2 1 false false
title3 2 false true

The Switch statement is similar to the ngIf and is structured as follows.

<div [ngSwitch]="positions.length">
  <div *ngSwitchCase="1">One</div>
  <div *ngSwitchCase="2">Two</div>
  <div *ngSwitchDefault>Default</div>
</div>

 

Two-way Binding

Two way binding is done using ngModels. The syntax is the banana-in-box – [( xxx )]

<input [(ngModel)] = "name">
{{ name }}

Note that in order to do two-way binding we must include the FormsModule in the component or module.

 

Component Communication

There are input and output decorators for components to communicate with it’s parents and children. To accept variables, we use Input as follows:

export class PositionComponent {
  @Input() title: string;
}

Now when calling the PositionComponent we would pass in the title string as part of the element’s property:

<position [title]="Some Title Here"></position>
Note that in the above example the title is being property-bound and so the Angular compiler will try to resolve it as an expression. If trying to pass the value directly, remove the brackets. Also on the child component we can use aliases to set the incoming parameter to another variable.
<position title="Some Title Here"></position>
 ...
 export class PositionComponent {
   @Input('title') internalTitle: string;
 }
For outputs, we use the EventEmitter and the Output keyword. The child component would emit the value as an Output event.
<position (eventFromChild)="onEventFromChild($event)"></position>
...
export class ChildComponent {
  @Output() thisEvent = new EventEmitter<null>();
  onSomeClick() {
    this.thisEvent.emit(); // bubbles the thisEvent variable up to the parent
  }
}

 

Content Projection / Transclusion

This is the inclusion of a content from one component into another component. This is done through a keyword tag – <ng-content></ng-content> In the example below, we are being selective in what part of the parent’s call to the position component is to be displayed in the position component.

<position title = "title1">
  <p class = "copyright" >Copyright 2017</p>
  <p>Lorem Ipsum</p>
</position>
...
<ng-content select=".copyright"></ng-content>

In the example above, the position child component would only be displaying the “Copyright 2017” paragraph which i got from its parent. It will not display the second paragraph with “lorem ipsum”. The following examples also shows how we can select based on element type and how to not select a specific class.

<ng-content select="p"></ng-content>
<ng-content select=":not(.copyright)"></ng-content>

 

Field Decorators

There is a field decorator “@HostBinding” that can be set inside a component to add or remove classes to the component. The example below also shows using a “@HostListener” so that it captures any mouse clicks on the page.

export class Example1Component {
  @HostBinding('class.text-danger') redText = true;

  @HostListener('click', ['$event']) onclick(event) {
    // do something here
  }
}

 

The “@ViewChild” field decorator allows template reference variable. In the example below, we can access the <position> element from the component class by setting it to the @ViewChild variable.

<position #myposition></position>
...
export class ExampleComponent {

  @ViewChild(PositionComponent) position: PositionComponent;
  // can reference the child component through the 'position' variable
}

 

If our component had reference the position child component several times, we can use the ‘@ViewChildern’ field decorator to reference the list. Note that this requires use of keyword QueryList, which is a list of the components.

@ViewChildren(PositionComponent) positions: QueryList<PositionComponent>;

 

The opposite of using @ViewChildren field decorators are the @ContentChild and @ContentChildren field decorators. These are used to reference the <ng-content> elements. So in the template example below, we would use @ViewChild to access the <position> elements and @ContentChild to access the <ng-content> element.

<position title='CFO'></position>
<position title='CIO'></position>
<position title='CTO'></position>
<ng-content></ng-content>

 

Component Lifecycle Hooks

Some common lifecycle hooks that can be used in components are shown below in the order of which they fire when loading a page.

  • constructor() – does DI
  • ngOnChanges() – handles input properties
  • ngOnInit() – all input properties initialized
  • ngDoCheck() – when an input property is changed
  • ngAfterContentInit() – when component content is initialized
  • ngAfterContentChecked() – content checked and initialized
  • ngAfterViewInit() – components view is to be initialized
  • ngAfterViewChecked() – when a view is checked
  • ngOnDestroy() – called right before instance is destroyed