14

I have an Angular2.0 component:

import {Component, View, FORM_DIRECTIVES} from 'angular2/angular2';

@Component({
  selector: 'font-size-component',
  properties: ['fontSize'],
  events: ['fontSizeChanged']
})
@View({
  template: `<input id="fontSize" [(ng-model)]="fontSize"/>`,
  directives: [FORM_DIRECTIVES]
})
export class FontSizeComponent {
  constructor() {

  }
}

Now, I want this component to trigger an event (using event-binding) when the input changes.

On Angular 1.X I had several options (ng-change or $scope.$wacth). I am looking for a similar solution, so when the input changes I will be able to use eventemitter and trigger an fontSizeChanged event.

Thanks,

Yaniv

3 Answers 3

20
  1. You can use javascript getters and setters. So your component would look like:
import {Component, View, FORM_DIRECTIVES, EventEmitter} from 'angular2/angular2';

@Component({
    selector: 'font-size-component',
    properties: ['fontSize'],
    events:     ['fontSizeChange']
})
@View({
    template: `
        <input id="fontSize" [(ng-model)]="fontSizeModel"/>
    `,
    directives: [FORM_DIRECTIVES]
})
export class FontSizeComponent {
    fontSize: string;
    fontSizeChange = new EventEmitter();

    get fontSizeModel() {
        return this.fontSize;
    }

    set fontSizeModel(value) {
        this.fontSizeChange.next(value);
    }
}

Check out this plnkr

  1. Slightly different solution is to use (input) event binding:
@Component({
    selector: 'font-size-component',
    properties: ['fontSize'],
    events:     ['fontSizeChange']
})
@View({
    template: `
        <input 
          id="fontSize" 
          [value]="fontSize" 
          (input)="fontSizeChange.next($event.target.value)"
        />
    `,
    directives: [FORM_DIRECTIVES]
})
export class FontSizeComponent {
    fontSize: string;
    fontSizeChange = new EventEmitter();
}

See this plnkr

Sign up to request clarification or add additional context in comments.

5 Comments

Wow - this is an awesome answer, thank you very much!! One question - in your first example I cannot see how can I initial the input with the incoming "fontSize" (attribute binding) data. Regarding the second example - is (input) equivalent to ng-change() (that I was looking for (:
You helped me a-lot - Your help is highly appreciated!
fontSizeChange.next is deprecated, please use fontSizeChange.emit instead.
In the meantime properties were changed to input and events to output
This is a more recent example very similar to the first one that helped me--the important part was the @Input only on setter: angular.io/docs/ts/latest/cookbook/…
18

You could also tap into the lifecycle hooks of Angular2. From the documentation:

ngOnChanges(changeRecord) { ... }
Called after every change to input properties and before processing content or child views.

See https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

Just add this method to your component class:

ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
  if (changes['fontSize']) { // fire your event }
}

The above guide includes a Plunkr for this: https://angular.io/resources/live-examples/lifecycle-hooks/ts/plnkr.html

2 Comments

This was what I looking for.
plunkr link dead :(
2

If you want to manually handle changes to the input you can separate out the short-hand [(ngModel)] by doing something like this:

<input id="fontSize" [ngModel]="fontSize" (ngModelChange)="fontSizeChange($event)"/>

Make sure that within the fontSizeChange($event) function you use the $event to assign the changed input value to the fontSize variable as this is no longer automatically handled.

When you use [(ngModel)] it is really doing something like this:

<input id="fontSize" [ngModel]="fontSize" (ngModelChange)="fontSize=$event" />

For more information you can refer to the official documentation: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#two-way-binding-with-ngmodel

Currently Angular 2 is still in beta so this is subject to change.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.