Monthly Archives: October 2017

Angular 2.0 and > – How do components communicate with each other

As we are already aware Angular follows component philosophy, it is component based, everything is a component. Components are the main way we build and specify elements and logic on the page. We define root component and then multiple child components to that root component and then grand child components to child components and this continues which builds a component hierarchy. So obviously in this components have to talk with each other to pass data or for notifications, there are 3 patterns of communication over here

  1. Parent to child
  2. Child to parent
  3. Communication between sibling components

1. Parent to Child

This can be achieved using the @Input, to define an input for a component, we use the @Input decorator.

1-Ang2-Comp-Comm

For example, our component needs a counter argument to initialize the counter in child component

Now we will define the @Input counter in component as below

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

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() counter = 0;
  @Output() childComponentNotification = new EventEmitter();
  constructor() { }

  ngOnInit() {
  }

  incrementCounter(){
    this.counter++;
    this.childComponentNotification.emit(this.counter);
  }
}

HTML of child component looks some thing like this

2-Ang2-Comp-Comm

As you can we have child component which has counter as Input propert from parent component, this input initializes the child components internal counter and whenever user clicks on the button in the child component

2. Child to Parent

Now when the user clicks on the button on child component it increments the counter, this increments needs to be notified to the parent component this is where @Output comes in to the picture. To be able to use our Output, we need to import and bind a new instance of the EventEmitter to it.   We have to call .emit() to emit an event to the parent. So in the above case we hook in the @Output childComponentNotification to the event onChildComponentNotification event function which has been defined in the parent component.. Here is the snippet.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Parent Component';
  private childCounter: Number;
  private childCounterRefInParent: Number;
  constructor(private ngZoneService: NgZone) {
    this.childCounter = 0;
    this.childCounterRefInParent = 0;
  }

  onChildNotificationReceived(childCounter: Number) {
    this.childCounterRefInParent = childCounter;
  }
}

HTML for app component of parent component display the incremented counter from child component.Incremented counter is been passed as event parameter.

3-Ang2-Comp-Comm

Advertisements

ngZone === $scope.$apply(). What is equivalent of $scope.$apply() in angular 2 and beyond…..

ngZone is an injectable service for executing work inside or outside of the Angular zone. The most common use of this service is to optimize performance when starting a work consisting of one or more asynchronous tasks that don’t require UI updates or error handling to be handled by Angular. Such tasks can be kicked off via runOutsideAngular and if needed, these tasks can reenter the Angular zone via run.

In Angular 2, change detection is automatic as opposed to Angular 1 that applys the change detection with the help of methods like $scope.$watch() and $scope.$digest().

Under the hood, Angular 2 uses something called Zones. In a nutshell, Zone.js intercepts all of the asynchronous APIs in the browser by monkey patching them.

Monkey patching is a technique to override, extend or even suppress the default behavior of a code segment without changing its source code. So when we call something like setTimeout — Angular 2 knows that and can trigger change detection and decide if she needs to update the DOM because setTimeout() is monkey patched.

Angular 2 gives us the ability to escape from change detection with the help of the ngZone service that exposes the runOutsideAngular method. Running functions via runOutsideAngular allows you to escape Angular’s zone and do work that doesn’t trigger Angular change-detection or is subject to Angular’s error handling.

We need to pass a function to this method and any future tasks scheduled from within this function will continue executing from outside of the Angular zone.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';

  constructor(private ngZoneService: NgZone){
    this.ngZoneService.runOutsideAngular(()=>{
      //Execute all Your code over here which needs to be executed 
      // outside of angular context
      // ...
      // ...
      // ...
      // ...
      // ...

      //Reenter 
      this,ngZoneService.run(()=>{
          console.log("Reenetering angular context....")
      });

    });
  }
}