One of the great new benefits of the new Angular binding style is that you are able to more accurately target what you are binding to. Formerly, the HTML attribute that was used as a directive or data token was simply used as a matching identifier. Now, you are able to use property bindings within the binding markup for both the input and output.
The code, links, and a live example of this is available at .
Suppose you had the following application:
[app/article.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article', template: ` <input #title (keydown)="setTitle(title.value)"> <h1>{{myTitle}}</h1> ` }) export class ArticleComponent { myTitle:string; setTitle(val:string):void { this.myTitle = val; } }
Your objective is to modify this so that it exhibits the following behavior:
<h1>
tag is not updated with the value of the input field until the user strikes the Enter key.<h1>
value does not match the value in the title input (call this state "stale"), the text color should be red. If it does match, it should be green.Both of these behaviors can be achieved with Angular 2's attribute property binding. First, you can change the event binding so that only an Enter key will invoke the callback:
[app/article.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article', template: ` <input #title (keydown.enter)="setTitle(title.value)"> <h1>{{myTitle}}</h1> ` }) export class ArticleComponent { myTitle:string; setTitle(val:string):void { this.myTitle = val; } }
Next, you can use Angular's style binding to directly assign a value to a style
property. This requires adding a Boolean to the controller object to maintain the state:
[app/article.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article', template: ` <input #title (keydown.enter)="setTitle(title.value)"> <h1 [style.color]="isStale ? 'red' : 'green'">{{myTitle}}</h1> ` }) export class ArticleComponent { myTitle:string = ''; isStale:boolean = false; setTitle(val:string):void { this.myTitle = val; } }
Closer, but this still provides no way of reaching a stale state. To achieve this, add another keydown
event binding:
[app/article.component.ts] import {Component} from '@angular/core'; @Component({ selector: 'article', template: ` <input #title (keyup.enter)="setTitle(title.value)" (keyup)="checkStale(title.value)"> <h1 [style.color]="isStale ? 'red' : 'green'"> {{myTitle}} </h1> ` }) export class ArticleComponent { myTitle:string = ''; private isStale:boolean = false; setTitle(val:string):void { this.myTitle = val; } checkStale(val:string):void { this.isStale = val !== this.myTitle; } }
With this, the color of the <h1>
tag should correctly keep track of whether the data is stale or not!
The simple explanation is that Angular provides you with a lot of syntactical sugar, but at a very basic level without involving a lot of complexity. If you were to inspect the keyup
event, you would of course notice that there is no enter
property available. Angular offers you a number of these pseudo properties so that checking the keyCode
of the pressed key is not necessary.
In a similar way, Angular also allows you to bind to and access style
properties directly. It is inferred that the style being accessed refers to the host element.
Note here that you have assigned two handlers to what is essentially the same event. Not only this, but rearranging the order of the binding markup will break this application's desired behavior.
When two handlers are assigned to the same event, Angular will execute the handlers in the order that they are defined in the markup.