在 Angular 中最典型的數(shù)據(jù)顯示方式,就是把 HTML 模板中的控件綁定到 Angular 組件的屬性昙衅。
本章驼抹,你將創(chuàng)建一個英雄列表組件祥绞。顯示英雄名字的列表冬阳,并根據(jù)條件在列表下方顯示一條消息蔗怠。
最終的用戶界面是這樣的:
使用插值表達式顯示組件屬性
要顯示組件的屬性启昧,最簡單的方式就是通過插值表達式 (interpolation) 來綁定屬性名。 要使用插值表達式疆柔,就把屬性名包裹在雙花括號里放進視圖模板咒精,如{{myHero}}
。
按照配置開發(fā)環(huán)境的說明旷档,創(chuàng)建一個名為displaying_data
的新項目模叙。
然后,到app_component.dart
文件鞋屈,修改組件的模板和代碼范咨。
修改完之后,應該是這樣的:
// lib/app_component.dart
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
template: '''
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
''',
)
class AppComponent {
final title = 'Tour of Heroes';
String myHero = 'Windstorm';
}
再把兩個屬性title
和myHero
添加到之前空白的組件中厂庇。
修改完的模板會使用雙花括號形式的插值表達式來顯示這兩個模板屬性:
template: '''
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
''',
Angular 自動從組件中提取title
和myHero
屬性的值渠啊,并且把這些值插入瀏覽器中。當這些屬性發(fā)生變化時权旷,Angular 就會自動更新顯示替蛉。
嚴格來說,“重新顯示”是在某些與視圖有關的異步事件之后發(fā)生的,例如躲查,按鍵它浅、定時器完成或?qū)?HTTP 請求的響應。
注意熙含,我們沒有調(diào)用 new
來創(chuàng)建AppComponent
類的實例罚缕,是 Angular 替我們創(chuàng)建了它艇纺。那么它是如何創(chuàng)建的呢怎静?
在@Component
注解中的 CSS 選擇器 selector
,指定一個名為<my-app>
的元素黔衡。該元素是index.html
的 body
里的占位符蚓聘。
// web/index.html(body)
<body>
<my-app>Loading...</my-app>
</body>
當你通過AppComponent
類(在web/main.ts
中)啟動應用時,Angular 在index.html
中查找一個<my-app>
元素盟劫,找到它夜牡,然后實例化一個AppComponent
的實例,并將其渲染到<my-app>
標簽中侣签。
現(xiàn)在運行應用塘装。它應該顯示出標題和英雄名:
內(nèi)聯(lián) (inline) 模板還是模板文件?
我們可以在兩種地方存放組件模板影所。使用template
屬性把它定義為內(nèi)聯(lián)的蹦肴,或者把模板定義在一個獨立的 HTML 文件中,再通過@Component
注解中的templateUrl
屬性猴娩,把它鏈接到組件元數(shù)據(jù)阴幌。
到底選擇內(nèi)聯(lián) HTML 還是獨立 HTML 取決于個人喜好、具體狀況和組織策略卷中。上面的應用選擇內(nèi)聯(lián) HTML矛双,是因為模板很小,而且沒有額外的 HTML 文件顯得這個演示簡單些蟆豫。
無論用哪種風格议忽,模板數(shù)據(jù)綁定在訪問組件屬性方面都是完全一樣的。
使用 *ngFor顯示一列屬性
要顯示一列英雄十减,先向組件中添加一個包含英雄名字的列表栈幸,然后把myHero
重新定義為列表中的第一個名字。
// lib/app_component.dart (class)
class AppComponent {
final title = 'Tour of Heroes';
List<String> heroes = [
'Windstorm',
'Bombasto',
'Magneta',
'Tornado',
];
String get myHero => heroes.first;
}
現(xiàn)在嫉称,在模板中使用 Angular 的ngFor
指令來顯示heroes
列表中的每一項侦镇。
template: '''
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
<p>Heroes:</p>
<ul>
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
</ul>
''',
directives: const [CORE_DIRECTIVES] // 使用ngFor 一定要聲明指令
這個界面使用了由 <ul>
和 <li>
標簽組成的無序列表。<li>
元素里的*ngFor
是 Angular 的“重復”指令织阅。它將<li>
元素(及其子元素)標記為“重復模板”:
<li *ngFor="let hero of heroes">
{{ hero }}
</li>
不要忘記
*ngFor
中的前導星號 (*)壳繁。它是語法中不可或缺的一部分。更多信息,見模板語法闹炉。
注意看ngFor
雙引號表達式中的hero
蒿赢,它是一個模板輸入變量。 更多模板輸入變量的信息渣触,見模板語法中的微語法羡棵。
Angular 為列表中的每個條目復制一個<li>
元素,在每個迭代中嗅钻,把hero
變量設置為當前條目(英雄)皂冰。Angular 把hero
變量作為雙花括號插值表達式的上下文。
本例中养篓,
ngFor
用于顯示一個列表秃流,但ngFor
可以為任意
Iterable 對象重復條目。
@Component(directives: …)
在模板中使用任何 Angular 指令之前柳弄,需要在組件的
@Component
注解的directives
列表中聲明它們舶胀。可以單獨的列出指令碧注,或者為了方便起見使用 CORE_DIRECTIVES:
// lib/app_component.dart (directives)
import 'package:angular/angular.dart';
@Component(
selector: 'my-app',
// ···
directives: [coreDirectives],
)
刷新瀏覽器∠ィ現(xiàn)在,英雄們出現(xiàn)在了一個無序列表中萍丐。
為數(shù)據(jù)創(chuàng)建一個類
應用代碼直接在組件內(nèi)部直接定義了數(shù)據(jù)轩端。作為演示還可以,但它顯然不是最佳實踐碉纺。
現(xiàn)在使用的是到一個字符串列表的綁定船万。在真實的應用中,大多數(shù)是綁定到一個專門的對象骨田。
要將此綁定轉(zhuǎn)換成使用專門的對象耿导,需要把這個英雄名字的列表變成Hero
對象的列表。因此态贤,你需要一個Hero
類舱呻。
在lib
目錄創(chuàng)建一個名為hero.dart
的新文件,內(nèi)容如下:
// lib/src/hero.dart
class Hero {
final int id;
String name;
Hero(this.id, this.name);
@override
String toString() => '$id: $name';
}
你定義了一個包含一個構造函數(shù)悠汽,兩個屬性(id
和name
)和一個toString()
方法的類箱吕。
使用 Hero 類
導入了Hero
類之后,AppComponent.heroes
屬性就可以返回一個Hero
對象類型的列表了柿冲。
// lib/app_component.dart
List<Hero> heroes = [
new Hero(1, 'Windstorm'),
new Hero(13, 'Bombasto'),
new Hero(15, 'Magneta'),
new Hero(20, 'Tornado')
];
Hero get myHero => heroes.first;
接下來茬高,修改模板。現(xiàn)在它顯示的是英雄的id
和name
假抄。修復它怎栽,只顯示英雄的name
屬性丽猬。
// lib/app_component.dart (template)
template: '''
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero.name}}</h2>
<p>Heroes:</p>
<ul>
<li *ngFor="let hero of heroes">
{{ hero.name }}
</li>
</ul>
''',
顯示上還和以前一樣,不過代碼更清晰了熏瞄。
通過 NgIf 進行條件顯示
有時脚祟,應用需要只在特定情況下顯示視圖或視圖的一部分。
讓我們來修改這個例子强饮,如果多于三位英雄由桌,顯示一條消息。
Angular 的ngIf
指令會根據(jù)一個布爾條件邮丰,插入或移除元素行您。通過把下面的段落添加到模板的底部,我們可以看到實際效果柠座。
// lib/app_component.dart (message)
<p *ngIf="heroes.length > 3">There are many heroes!</p>
不要忘了
*ngIf
中的前導星號 (*
)邑雅。它是本語法中不可或缺的一部分。 更多ngIf
和*
的內(nèi)容妈经,見模板語法的 ngIf 部分。
雙引號中的模板表達式捧书,*ngIf ="heros.length > 3"
吹泡,看起來就像是 Dart。當組件中的英雄列表有三個以上時经瓷,Angular 把這個段落添加到 DOM 中爆哑,于是消息顯示了出來。如果有3個或少于3個舆吮,Angular 會忽略這個段落揭朝,所以就沒有信息顯示。更多信息色冀,見模板語法中的模板表達式部分潭袱。
Angular 并不是在顯示和隱藏這條消息,它是在從 DOM 中添加和移除這個段落元素锋恬。這會提高性能屯换,特別是在一些大的項目中有條件地包含或排除一大堆帶著很多數(shù)據(jù)綁定的 HTML 時。
試一下与学。因為列表中有四個條目彤悔,所以消息顯示了出來∷魇兀回到app_component.dart
晕窑,從英雄列表中刪除或注釋掉一個元素。瀏覽器刷新后卵佛,信息應該不存在了杨赤。
總結
現(xiàn)在你學會了如何使用:
- 帶有雙花括號的插值表達式來顯示一個組件屬性蓝丙。
- ngFor 來顯示一列條目。
- 用一個 Dart 類來為組件描述模型數(shù)據(jù)并顯示模型的屬性望拖。
- ngIf 來根據(jù)一個布爾表達式有條件的顯示一段HTML渺尘。
下一步