// hero-detail.component.ts
import {Component} from 'angular2/core';
import {Hero} from './hero';
@Component({
selector: 'my-hero-detail',
template: `
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
</div>
`,
inputs: ['hero']
})
export class HeroDetailComponent {
public hero: Hero;
}
// app.component.ts
import {Component} from 'angular2/core';
import {Hero} from './hero';
import {HeroDetailComponent} from './hero-detail.component';
@Component({
selector: 'my-app',
template:`
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="#hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
<my-hero-detail [hero]="selectedHero"></my-hero-detail>
`,
styles:[`
.selected {
background-color: #CFD8DC !important;
color: white;
}
.heroes {
margin: 0 0 2em 0;
list-style-type: none;
padding: 0;
width: 10em;
}
.heroes li {
cursor: pointer;
position: relative;
left: 0;
background-color: #EEE;
margin: .5em;
padding: .3em 0em;
height: 1.6em;
border-radius: 4px;
}
.heroes li.selected:hover {
color: white;
}
.heroes li:hover {
color: #607D8B;
background-color: #EEE;
left: .1em;
}
.heroes .text {
position: relative;
top: -3px;
}
.heroes .badge {
display: inline-block;
font-size: small;
color: white;
padding: 0.8em 0.7em 0em 0.7em;
background-color: #607D8B;
line-height: 1em;
position: relative;
left: -1px;
top: -4px;
height: 1.8em;
margin-right: .8em;
border-radius: 4px 0px 0px 4px;
}
`],
directives: [HeroDetailComponent]
})
export class AppComponent {
public title = 'Tour of Heroes';
public heroes = HEROES;
public selectedHero: Hero;
onSelect(hero: Hero) { this.selectedHero = hero; }
}
var HEROES: Hero[] = [
{ "id": 11, "name": "Mr. Nice" },
{ "id": 12, "name": "Narco" },
{ "id": 13, "name": "Bombasto" },
{ "id": 14, "name": "Celeritas" },
{ "id": 15, "name": "Magneta" },
{ "id": 16, "name": "RubberMan" },
{ "id": 17, "name": "Dynama" },
{ "id": 18, "name": "Dr IQ" },
{ "id": 19, "name": "Magma" },
{ "id": 20, "name": "Tornado" }
];
// hero.ts
export interface Hero {
id: number;
name: string;
}
为了遵守 Single Responsibility Principle ,将显示hero详细信息抽离成为独立的component。
抽离时需要记住几个点:
从
AppComponent
里抽离html到独立的HeroDetailComponent
,并替换为<my-hero-detail></my-hero-detail>
AppComponent
需要 importHeroDetailComponent
两个文件都需要用到
Hero
这个interface
,也抽离为独立文件 hero.ts,并用 export 对外开放接口通过 input 为
AppComponent
和HeroDetailComponent
绑定数据,<my-hero-detail [hero]="selectedHero"></my-hero-detail>
,这里的hero是一个绑定数据的目标属性,没有设置这个目标属性会报错而后在
HeroDetailComponent
的 component 添加一个 metadatainputs: ['hero']
至此,父子component间的数据通道打通,不过刷新页面仍看不到效果,也无报错,是因angular忽略了新标签
<my-hero-detail></my-hero-detail>
。浏览器无法识别的标签和属性angular也无法识别。在
AppComponent
添加directives: [HeroDetailComponent]
来告知angularjs
directives : Array<Type | any[]>
Specifies a list of directives that can be used within a template.