AngularJS2 Tour of Heroesしてみる

Tutorial: Tour of Heroes - ts

今回AngularJS2のLearning Pathの3までやってみました。


Interface or Class?

If we need a Hero that goes beyond simple properties, 
a Hero with logic and behavior, we must define a class. 

If we only need type checking, the interface is sufficient and lighter weight.

Transpiling a class to JavaScript produces code. 
Transpiling an interface produces — nothing. 

If the class does nothing (and there is nothing for a Hero class to do right now)
, we prefer an interface.


Two-Way Binding

  • [(ngModel)]="XXXXXXXX"を使用する
<h2>{{}} details!</h2>
<input [(ngModel)]="" placeholder="name">



<li *ngFor="#hero of heroes">
  <span class="badge">{{}}</span> {{}}


The (*) prefix to ngFor indicates that the <li> element 
and its children constitute a master template.

The ngFor directive iterates over the heroes array returned by the AppComponent.heroes property 
and stamps out instances of this template.

The # prefix before "hero" identifies the hero as a local template variable. 

Focus on the event binding



The parenthesis identify the <li> element’s click event as the target. 
The expression to the right of the equal sign calls the AppComponent method, 
onSelect(), passing the local template variable hero as an argument.

Expose the selected hero

public selectedHero: Hero;



<div *ngIf="selectedHero">


Styling the selection

[class.selected]="hero === selectedHero"


Naming conventions

HeroDetailComponent is in a file named hero-detail.component.ts.

All of our component names end in "Component". All of our component file names end in ".component".


AppComponent binds its selectedHero property to the hero property of our HeroDetailComponent

<my-hero-detail [hero]="selectedHero"></my-hero-detail>

inputs: ['hero']

Notice that the hero property is the target of a property binding — it's in square brackets to the left of the (=).

Angular insists that we declare a target property to be an input property.
If we don't, Angular rejects the binding and throws an error.

The directives array

A browser ignores HTML tags and attributes that it doesn't recognize. 
So does Angular.

We've imported HeroDetailComponent, 
we've used it in the template, 
but we haven't told Angular about it.
We tell Angular about it by listing it in the metadata directives array. 



we'll create a single reusable data service and learn to inject it in the components that need it.

import {Injectable} from 'angular2/core';

export class HeroService {

※TypeScript sees the @Injectable() decorator and emits metadata about our service, metadata that Angular may need to inject other dependencies into this service.

Inject the HeroService

・import {HeroService} from './hero.service';
・constructor(private _heroService: HeroService) { }
・providers: [HeroService]

※We have to teach the injector how to make a HeroService by registering a HeroService provider.
※The AppComponent can use that service to get heroes and so can every child component of its component tree.

The ngOnInit Lifecycle Hook

The constructor is for simple initializations like wiring constructor parameters to properties.
It's not for heavy lifting.

Angular will call it if we implement the Angular ngOnInit Lifecycle Hook.
Angular offers a number of interfaces for tapping into critical moments in the component lifecycle
: at creation, after each change, and at its eventual destruction.

Each interface has a single method. When the component implements that method, Angular calls it at the appropriate time.

We write an ngOnInit method with our initialization logic inside and leave it to Angular to call it at the right time.

import {OnInit} from 'angular2/core';

export class AppComponent implements OnInit {
  constructor(private _heroService: HeroService) { }
  getHeroes() {
    this.heroes = this._heroService.getHeroes();
  ngOnInit() {


Async Services and Promises


getHeroes() {
  this._heroService.getHeroes().then(heroes => this.heroes = heroes);

getHeroes() {
  return Promise.resolve(HEROES);

Appendix: Shadowing the parent's service