Angular 2: Property binding, event binding, headaches

angular

I have been looking at Angular 2 lately. After being disappointed with the tutorials online, I decided to write my own cookbook on property and event binding.

Property binding

Assuming we want to pass myProp from my-parent to my-child, we need the following.

1) In my-parent template:

<my-child [myProp]="prop" />

Note that in this case “prop” is interpreted meaning it will refer to “this.prop” in your parent template. If you want to have a string you can instead use [myProp]="'prop'"

2)  In the child:

2.1) The child controller

You need to declare the property, and that you are inputting it from the parent.

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

@Component({    
  selector: 'my-child',    
  templateUrl: './myChild.component.html',
  styleUrls: []
})
export class myChildComponent implements OnInit {
  // Declare the property as an input
  @Input() myProp: number;
  
  constructor() {     
    //note; myProp will not yet be defined here..    
  }
  
  ngOnInit() {
    console.log(this.myProp); // will be defined here!
  }
}

The Input module is needed to specify that myProp is an input, coming from the parent.

The ngOnInit() is not needed, but it’s important to make this point: the value will not be set until ngOnInit() is called, which of course is when the component is ready

 

2.2) The child template:
Of course, you can just use myProp in the template, just like any other variable.

Hello! {{ myProp }}

And that’s it! The property should now be bound to the child!

Event binding

Catch the child’s events from the parent

 

Let’s change our template code from before:

<my-child [myProp]="prop" (onPropChange)="onPropChange($event)"</strong> />

onPropChange is the name of the event we’re listening to, of course, and the value is the function that is called.

Then we can add the following in our parent component:

import { Component, Input, EventEmitter } from '@angular/core';
...
export class myParentCompnent {
 ... 
  onPropChange(prop) {    
    console.log("changed value", prop);   
  }
}

We need EventEmitter here, and we’ve defined our onPropChange function.

Now in our child, we need to trigger the event somehow.

The JS:

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

export class myChildComponent implements OnInit {    
   ..  
   prop: number = 0;
   @Output() onPropChange = new EventEmitter();
   
   triggerChange(prop) {
      this.onPropChange.emit(this.prop);   
   }
}

A few things to mention here

  1. Both EventEmitter and Output are needed. EventEmitter, is of course needed to send the event, and Output declares that the component “outputs” the specified property
  2. We declare our change event as an EventEmitter and as an Output. See the <number> by EventEmitter? This specifies that the value we’re sending is a number!
  3. the emit() call near the end is how the event is emitted.

 

Finally, we make a button that’s clicked to trigger the event:

<button (click)="triggerChange(++prop)">Click!</button>

This should demonstrate both how our custom event works and how the built-in click event works at once.

Note that we can call the this.onPropChange.emit() code when we need to send the event; it doesn’t have to be on click. I just used that because it’s a convenient example!

Anyway, now when you click on the button, the parent’s code should be called that will ‘log’ the result.

Two-way binding

 

Angular 1 had ng-model, and Angular2 still has ngModal, which can be used for two-way binding.

The module

First of all, ngModal isn’t enabled by default, so you need to enable it like so:

In your app module, add the following:

import { FormsModule } from '@angular/forms';

The template

When you want to bind two-ways with one of your properties in your template, you use [(ngModel)] =..

 

For example, if your controller had the following:

import { Component } from '@angular/core';
export class myCoolComponent implements OnInit {
   ..      
   prop: number = 0;
}

You can easily bind to the “prop” property:

<input type="text" [(ngModel)]="prop" />

 

That’s actually all you need! Now, this.prop will change in your controller code if you change the input value and vise-versa.

One thought on “Angular 2: Property binding, event binding, headaches

Leave a Comment

Your email address will not be published. Required fields are marked *