chore(toh): change inputs array for input decorator/hero now a class

This commit is contained in:
Foxandxss 2016-03-24 13:31:27 +01:00 committed by Ward Bell
parent 10877bdbfc
commit 5f73911eaf
22 changed files with 57 additions and 77 deletions

View File

@ -1,4 +1,4 @@
export interface Hero {
export class Hero {
name: string;
}

View File

@ -1,12 +1,12 @@
// #docregion pt1
import {Component} from 'angular2/core';
// #docregion hero-interface-1
interface Hero {
// #docregion hero-class-1
export class Hero {
id: number;
name: string;
}
// #enddocregion hero-interface-1
// #enddocregion hero-class-1
@Component({
selector: 'my-app',

View File

@ -1,7 +1,7 @@
// #docregion pt2
import {Component} from 'angular2/core';
interface Hero {
export class Hero {
id: number;
name: string;
}
@ -37,7 +37,7 @@ interface Hero {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
width: 15em;
}
.heroes li {
cursor: pointer;

View File

@ -32,7 +32,7 @@ import {HeroDetailComponent} from './hero-detail.component';
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
width: 15em;
}
.heroes li {
cursor: pointer;

View File

@ -1,7 +1,8 @@
// #docplaster
// #docregion
// #docregion v1
import {Component} from 'angular2/core';
import {Component, Input} from 'angular2/core';
// #enddocregion v1
// #docregion hero-import
import {Hero} from './hero';
@ -10,7 +11,7 @@ import {Hero} from './hero';
// #docregion v1
@Component({
selector: 'my-hero-detail',
// #enddocregion v1
// #enddocregion v1
// #docregion template
template: `
<div *ngIf="hero">
@ -21,18 +22,18 @@ import {Hero} from './hero';
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
</div>
`,
`
// #enddocregion template
// #docregion inputs
inputs: ['hero']
// #enddocregion inputs
// #docregion v1
// #docregion v1
})
export class HeroDetailComponent {
// #enddocregion v1
// #docregion hero
// #docregion hero-input
@Input()
// #docregion hero
hero: Hero;
// #enddocregion hero
// #enddocregion hero
// #enddocregion hero-input
// #docregion v1
}
// #enddocregion v1

View File

@ -1,5 +1,5 @@
// #docregion
export interface Hero {
export class Hero {
id: number;
name: string;
}

View File

@ -32,7 +32,7 @@ import {HeroService} from './hero.service';
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
width: 15em;
}
.heroes li {
cursor: pointer;

View File

@ -1,5 +1,5 @@
// #docregion
import {Component} from 'angular2/core';
import {Component, Input} from 'angular2/core';
import {Hero} from './hero';
@Component({
@ -15,9 +15,8 @@ import {Hero} from './hero';
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
</div>
`,
inputs: ['hero']
`
})
export class HeroDetailComponent {
hero: Hero;
@Input() hero: Hero;
}

View File

@ -1,4 +1,4 @@
export interface Hero {
export class Hero {
id: number;
name: string;
}

View File

@ -2,10 +2,10 @@
// #docregion
// #docregion v2
// #docregion import-oninit
import { Component, OnInit } from 'angular2/core';
import { Component, Input, OnInit } from 'angular2/core';
// #enddocregion import-oninit
// #docregion import-route-params
import {RouteParams} from 'angular2/router';
import { RouteParams } from 'angular2/router';
// #enddocregion import-route-params
import { Hero } from './hero';
@ -20,15 +20,14 @@ import { HeroService } from './hero.service';
templateUrl: 'app/hero-detail.component.html',
// #enddocregion template-url
// #enddocregion v2
styleUrls: ['app/hero-detail.component.css'],
inputs: ['hero']
styleUrls: ['app/hero-detail.component.css']
// #docregion v2
})
// #enddocregion extract-template
// #docregion implement
export class HeroDetailComponent implements OnInit {
// #enddocregion implement
hero: Hero;
@Input() hero: Hero;
// #docregion ctor
constructor(

View File

@ -1,4 +1,4 @@
export interface Hero {
export class Hero {
id: number;
name: string;
}

View File

@ -6,7 +6,7 @@
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
width: 15em;
}
.heroes li {
cursor: pointer;

View File

@ -26,5 +26,5 @@ import {HeroService} from './hero.service';
{path: '/detail/:id', name: 'HeroDetail', component: HeroDetailComponent}
])
export class AppComponent {
public title = 'Tour of Heroes';
title = 'Tour of Heroes';
}

View File

@ -9,7 +9,7 @@ import {HeroService} from './hero.service';
styleUrls: ['app/dashboard.component.css']
})
export class DashboardComponent implements OnInit {
public heroes: Hero[] = [];
heroes: Hero[] = [];
constructor(private _heroService: HeroService, private _router: Router) { }

View File

@ -1,4 +1,4 @@
import {Component, OnInit} from 'angular2/core';
import {Component, Input, OnInit} from 'angular2/core';
import {RouteParams} from 'angular2/router';
import {Hero} from './hero';
@ -7,11 +7,10 @@ import {HeroService} from './hero.service';
@Component({
selector: 'my-hero-detail',
templateUrl: 'app/hero-detail.component.html',
styleUrls: ['app/hero-detail.component.css'],
inputs: ['hero']
styleUrls: ['app/hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
public hero: Hero;
@Input() hero: Hero;
constructor(private _heroService: HeroService,
private _routeParams: RouteParams) {

View File

@ -1,4 +1,4 @@
export interface Hero {
export class Hero {
id: number;
name: string;
}

View File

@ -6,7 +6,7 @@
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
width: 15em;
}
.heroes li {
cursor: pointer;

View File

@ -11,8 +11,8 @@ import {Hero} from './hero';
directives: [HeroDetailComponent]
})
export class HeroesComponent implements OnInit {
public heroes: Hero[];
public selectedHero: Hero;
heroes: Hero[];
selectedHero: Hero;
constructor(private _heroService: HeroService, private _router: Router) { }

View File

@ -66,31 +66,15 @@ code-example(format="" language="bash").
### Hero object
At the moment, our hero is just a name. Our hero needs more properties.
Let's convert the `hero` from a literal string to an interface.
Let's convert the `hero` from a literal string to a class.
Create a `Hero` interface with `id` and `name` properties.
Create a `Hero` class with `id` and `name` properties.
For now put this near the top of the `app.component.ts` file, just below the import statement.
+makeExample('toh-1/ts/app/app.component.ts', 'hero-interface-1', 'app.component.ts (Hero interface)')(format=".")
.l-sub-section
:marked
#### Interface or Class?
Why a `Hero` interface and not a `Hero` class?
We want a strongly typed `Hero`. We get strong typing with either option.
Our choice depends on how we intend to use the `Hero`.
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.
Lighter weight? Transpiling a class to JavaScript produces code.
Transpiling an interface produces &mdash; nothing.
If the class does nothing (and there is nothing for a `Hero` class to do right now),
we prefer an interface.
+makeExample('toh-1/ts/app/app.component.ts', 'hero-class-1', 'app.component.ts (Hero class)')(format=".")
:marked
Now that we have a `Hero` interface, lets refactor our components `hero` property to be of type `Hero`.
Now that we have a `Hero` class, lets refactor our components `hero` property to be of type `Hero`.
Then initialize it with an id of `1` and the name, "Windstorm".
+makeExample('toh-1/ts-snippets/app.component.snippets.pt1.ts', 'hero-property-1', 'app.component.ts (Hero property)')(format=".")

View File

@ -51,13 +51,13 @@ code-example(format="." language="bash").
+makeExample('toh-2/ts/app/app.component.ts', 'hero-array', 'app.component.ts (Hero array)')
:marked
The `HEROES` array is of type `Hero`, the interface defined in part one,
The `HEROES` array is of type `Hero`, the class defined in part one,
to create an array of heroes.
We aspire to fetch this list of heroes from a web service, but lets take small steps
first and display mock heroes.
### Exposing heroes
Lets create a public property in `AppComponent` that exposes the heroes for binding.
Lets create a property in `AppComponent` that exposes the heroes for binding.
+makeExample('toh-2/ts-snippets/app.component.snippets.pt2.ts', 'hero-array-1', 'app.component.ts (Hero array property)')

View File

@ -73,14 +73,13 @@ code-example(format="." language="bash").
:marked
-->
:marked
We begin by importing the `Component` function from Angular so that we have it handy when we create
the metadata for our component.
We begin by importing the `Component` and `Input` decorators from Angular because we're going to need them soon.
We create metadata with the `@Component` decorator where we
specify the selector name that identifies this component's element.
Then we export the class to make it available to other components.
When we finish here, we'll import it into `AppComponent` and refer to its `<my-hero-detail>` element.
When we finish here, we'll import it into `AppComponent` and create a corresponding `<my-hero-detail>` element.
:marked
#### Hero Detail Template
At the moment, the *Heroes* and *Hero Detail* views are combined in one template in `AppComponent`.
@ -100,18 +99,18 @@ code-example(format="." language="bash").
Lets add that `hero` property we were talking about to the component class.
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero')
:marked
Uh oh. We declared the `hero` property as type `Hero` but our `Hero` interface is over in the `app.component.ts` file.
We have two components, each in their own file, that need to reference the `Hero` interface.
Uh oh. We declared the `hero` property as type `Hero` but our `Hero` class is over in the `app.component.ts` file.
We have two components, each in their own file, that need to reference the `Hero` class.
We solve the problem by relocating the `Hero` interface from `app.component.ts` to its own `hero.ts` file.
We solve the problem by relocating the `Hero` class from `app.component.ts` to its own `hero.ts` file.
+makeExample('toh-3/ts/app/hero.ts', null, 'hero.ts (Exported Hero interface)')(format=".")
+makeExample('toh-3/ts/app/hero.ts', null, 'hero.ts (Exported Hero class)')(format=".")
:marked
We export the `Hero` interface from `hero.ts` because we'll need to reference it in both component files.
We export the `Hero` class from `hero.ts` because we'll need to reference it in both component files.
Add the following import statement near the top of both `app.component.ts` and `hero-detail.component.ts`.
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-import', 'hero-detail.component.ts and app.component.ts (Import the Hero interface)')
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-import', 'hero-detail.component.ts and app.component.ts (Import the Hero class)')
:marked
#### The *hero* property is an ***input***
@ -137,14 +136,13 @@ code-example(format=".").
*source* properties do not.
:marked
There are a couple of ways we can declare that `hero` is an *input*.
We'll do it by adding an `inputs` array to the `@Component` metadata.
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'inputs')
We'll do it the way we *prefer*, by annotating the `hero` property with the `@Input` decorator that we imported earlier.
+makeExample('toh-3/ts/app/hero-detail.component.ts', 'hero-input')(format='.')
.l-sub-section
:marked
Learn about the `@Input()` decorator way in the
Learn more about the `@Input()` decorator in the
[Attribute Directives](../guide/attribute-directives.html#input) chapter.
:marked
.l-main-section
:marked

View File

@ -113,7 +113,7 @@ code-example(format="." language="bash").
We'll move the mock data to its own file.
Cut the `HEROES` array from `app.component.ts` and paste it to a new file in the `app` folder named `mock-heroes.ts`.
We copy the `import {Hero} ...` statement as well because the heroes array uses the `Hero` interface.
We copy the `import {Hero} ...` statement as well because the heroes array uses the `Hero` class.
+makeExample('toh-4/ts/app/mock-heroes.ts', null, 'mock-heroes.ts (Heroes array)')
:marked