In this page, you will expand "Heroes Guide" application, it displays a list of heroes, and allows the user to select a hero to view the details of the hero.
Create mock (mock) Heroic data
You need some heroes data for display.
Eventually, you will get its data from a remote server. But now, you need to create some analog hero (some mock Heroes) , and assuming that the data is retrieved from a remote server.
In src/app/
Create a folder called mock-heroes.ts
files. Define a constant array contains ten heroes HEROES
, and export it. The file is this.
import
{ Hero } from
'./hero'
;
export
const
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'
}
];
|
Show Heroes
You want HeroesComponent
the top of the display that list of heroes.
Open the HeroesComponent
class file, and imported analog HEROES 数据。
import
{ HEROES } from
'../mock-heroes'
;
|
Was added to a class heroes
attribute, so that these may be exposed heroes, for binding.
export
class
HeroesComponent
implements
OnInit {
heroes = HEROES;
|
Use *
ngFor list these heroes
Open the HeroesComponent
template file, with the following modifications:
- Add on top
<h2>
- Then add HTML elements represent unordered list (
<ul>
) - In
<ul>
inserting one<li>
element to display a singlehero
attribute. - Embellishment on some CSS class (Later you will add more CSS styles).
Upon completion should appear as follows:
heroes.component.html (heroes template)
content_copy
<h2>My Heroes</h2>
<ul
class
=
"heroes"
>
<li>
<span
class
=
"badge"
>{{hero.id}}</span> {{hero.name}}
</li>
</ul>
|
Now, the <li>
modification like this:
<li *ngFor=
"let hero of heroes"
>
|
*ngFor
Angular of a polygraph (Repeater) instruction. It will host its replication data for each element in the list.
In this example,
<li>
It is*
ngFor host elementsheroes
That is, from theHeroesComponent
list of classes.- When traversing the list in turn,
hero
will save the current hero object for each iteration.
Do not forget ngFor front asterisk (
*
), which is a key part of the syntax.
After the browser refresh list of heroes emerged.
To apply a style sheet heroes
Heroes list should be attractive, and when users move the mouse over a hero and a hero when you select from the list, it should give visual feedback.
In the first chapter of the tutorial , you worked in styles.css
for the entire application set some basic style. But that does not contain the required style sheet hero list style.
Of course, you can put more styles added to styles.css
, and let it as you add more components and expanding.
But there is a better way. You can define private styles belonging to specific components, and make all the necessary components (code, HTML and CSS) are put together.
This way you make it easier to reuse the component in other places, and even global style and here is not the same, the components still have the desired appearance.
You can use a variety of ways define private style, or inline in @
Component.styles array, or @
Component.styleUrls noted stylesheet file.
When CLI is generated HeroesComponent
, it is also HeroesComponent
creating a blank heroes.component.css
style sheet file, and let @
Component.styleUrls point to it, like this:
@Component
({
selector:
'app-heroes'
,
templateUrl:
'./heroes.component.html'
,
styleUrls: [
'./heroes.component.css'
]
})
|
Open the heroes.component.css
file, and the HeroesComponent
private paste the CSS styles. You can at the bottom of this guide to see the final code to find them.
@
Component metadata specified styles and style sheets are limited to this assembly. heroes.component.css
The style will only effect HeroesComponent
, will not affect the HTML external components, it will not affect the other components in the HTML.
Master-slave structure
When the user master when clicking on a list of heroes, this component should display the selected hero in the bottom of the page details .
In this section, you will listen for click events hero entry and update details of heroes.
Add click
event binding
Beyond <li>
the elements into a binding code Click event:
<li *ngFor=
"let hero of heroes"
(click)=
"onSelect(hero)"
>
|
This is Angular event binding example of the syntax.
click
Angular outside the parentheses will monitor this <li>
element of click
the event. When the user clicks <li>
when, Angular expression will be executed onSelect(hero)
.
onSelect()
It is HeroesComponent
a method on, you will soon write it. Angular will clicked <li>
on the hero
object passed to it, this hero
is in front in *
ngFor that the definition of the expression.
Add click
event handlers
The component of the hero
property changed its name selectedHero
, but do not assign to it. Because there is no application has just started the selected hero .
Add the following onSelect()
method, it will be the template clicked hero assigned to component selectedHero
properties.
selectedHero: Hero;
onSelect(hero: Hero):
void
{
this
.selectedHero = hero;
}
|
Modify the details template
The template reference is still the old hero
property, but it does not exist. The hero
renamed selectedHero
.
<h2>{{selectedHero.name | uppercase}} Details</h2>
<div><span>id: </span>{{selectedHero.id}}</div>
<div>
<label>name:
<input [(ngModel)]=
"selectedHero.name"
placeholder=
"name"
>
</label>
</div>
|
Refresh your browser, the application hung up.
Open the browser developer tools, its console shows the following error message:
HeroesComponent.html:
3
ERROR TypeError: Cannot read property
'name'
of undefined
|
What is the problem?
When the application starts, selectedHero
Shi undefined
, designed so .
But binding expression template referenced selectedHero
property (expressed as {{
selectedHero.name}}
), which is bound to fail, because you have not been selected hero yet.
Now, from the list, just click on an entry. Application normal again. Heroes appear in the list, and details of the hero's point is also shown in the bottom of the page.
Repair - Use * ngIf blank to hide details
This component should only when selectedHero
if there is a display details of the selected hero.
HTML to display the details of hero wrapped in a <div>
middle. Angular and adding to this div *
ngIf command, its value is set selectedHero
.
Do not forget ngIf front asterisk (
*
), which is a key part of the syntax.
<div *ngIf=
"selectedHero"
>
<h2>{{selectedHero.name | uppercase}} Details</h2>
<div><span>id: </span>{{selectedHero.id}}</div>
<div>
<label>name:
<input [(ngModel)]=
"selectedHero.name"
placeholder=
"name"
>
</label>
</div>
</div>
|
浏览器刷新之后,英雄名字的列表又出现了。 详情部分仍然是空。 点击一个英雄,它的详情就出现了。 这个应用看起来又再次工作正常显示了。 英雄显示在列表中,当你单击英雄的名字的时候,有关你单击英雄的详细信息就显示在页面的底部了。
为什么这样是正常的
当 selectedHero
为 undefined
时,ngIf 从 DOM 中移除了英雄详情。因此也就不用担心
selectedHero
的绑定了。
当用户选择一个英雄时,selectedHero
也就有了值,并且 ngIf 把英雄的详情放回到 DOM 中。
给所选英雄添加样式
所有的 <li>
元素看起来都是一样的,因此很难从列表中识别出所选英雄。
如果用户点击了“Magneta”,这个英雄应该用一个略有不同的背景色显示出来,就像这样:
所选英雄的颜色来自于你前面添加的样式中的 CSS 类 .selected
。 所以你只要在用户点击一个 <li>
时把 .selected
类应用到该元素上就可以了。
Angular 的 CSS 类绑定机制让根据条件添加或移除一个 CSS 类变得很容易。 只要把 [class.some-css-class]="some-condition"
添加到你要施加样式的元素上就可以了。
在 HeroesComponent
模板中的 <li>
元素上添加 [class.selected]
绑定,代码如下:
[
class
.selected]=
"hero === selectedHero"
|
如果当前行的英雄和 selectedHero
相同,Angular 就会添加 CSS 类 selected
,否则就会移除它。
最终的 <li>
是这样的:
<li *ngFor=
"let hero of heroes"
[
class
.selected]=
"hero === selectedHero"
(click)=
"onSelect(hero)"
>
<span
class
=
"badge"
>{{hero.id}}</span> {{hero.name}}
</li>
|
查看最终代码
下面是本页面中所提及的代码文件,包括 HeroesComponent
的样式。
对应的文件列表和代码链接如下:
文件名
|
源代码
|
---|---|
src/app/heroes/heroes.component.ts | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.ts |
src/app/heroes/heroes.component.html | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.html |
src/app/heroes/heroes.component.css | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.css |
小结
- Hero Guide application displays a list of heroes from view in a primary.
- Users can choose a hero, and the hero's view details.
- You use
*
ngFor shows a list. - You use
*
ngIf to conditionally include or exclude some HTML. - You can
class
bind to switch CSS style class.
https://www.cwiki.us/display/AngularZH/Display+a+Heroes+List