顯示數據

版本:Angular 5.0.0-alpha

在 Angular 中最典型的數據顯示方式,就是把 HTML 模板中的控件綁定到 Angular 組件的屬性。

本章,你將創建一個英雄列表組件。顯示英雄名字的列表,并根據條件在列表下方顯示一條消息。

最終的用戶界面是這樣的:


在線示例(查看源碼)演示了本章描述的所有語法和代碼片段。

使用插值表達式顯示組件屬性

要顯示組件的屬性,最簡單的方式就是通過插值表達式 (interpolation) 來綁定屬性名。 要使用插值表達式,就把屬性名包裹在雙花括號里放進視圖模板,如{{myHero}}

按照配置開發環境的說明,創建一個名為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';
}

再把兩個屬性titlemyHero添加到之前空白的組件中。
修改完的模板會使用雙花括號形式的插值表達式來顯示這兩個模板屬性:

template: '''
  <h1>{{title}}</h1>
  <h2>My favorite hero is: {{myHero}}</h2>
''',

Angular 自動從組件中提取titlemyHero屬性的值,并且把這些值插入瀏覽器中。當這些屬性發生變化時,Angular 就會自動更新顯示。

嚴格來說,“重新顯示”是在某些與視圖有關的異步事件之后發生的,例如,按鍵、定時器完成或對 HTTP 請求的響應。

注意,我們沒有調用 new 來創建AppComponent類的實例,是 Angular 替我們創建了它。那么它是如何創建的呢?

@Component注解中的 CSS 選擇器 selector,指定一個名為<my-app>的元素。該元素是index.htmlbody 里的占位符。

// web/index.html(body)

<body>
  <my-app>Loading...</my-app>
</body>

當你通過AppComponent類(在web/main.ts中)啟動應用時,Angular 在index.html中查找一個<my-app>元素,找到它,然后實例化一個AppComponent的實例,并將其渲染到<my-app>標簽中。

現在運行應用。它應該顯示出標題和英雄名:

內聯 (inline) 模板還是模板文件?

我們可以在兩種地方存放組件模板。使用template屬性把它定義為內聯的,或者把模板定義在一個獨立的 HTML 文件中,再通過@Component注解中的templateUrl屬性,把它鏈接到組件元數據。

到底選擇內聯 HTML 還是獨立 HTML 取決于個人喜好、具體狀況和組織策略。上面的應用選擇內聯 HTML,是因為模板很小,而且沒有額外的 HTML 文件顯得這個演示簡單些。

無論用哪種風格,模板數據綁定在訪問組件屬性方面都是完全一樣的。

使用 *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;
}

現在,在模板中使用 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],
)

刷新瀏覽器。現在,英雄們出現在了一個無序列表中。


為數據創建一個類

應用代碼直接在組件內部直接定義了數據。作為演示還可以,但它顯然不是最佳實踐。

現在使用的是到一個字符串列表的綁定。在真實的應用中,大多數是綁定到一個專門的對象。

要將此綁定轉換成使用專門的對象,需要把這個英雄名字的列表變成Hero對象的列表。因此,你需要一個Hero類。

lib目錄創建一個名為hero.dart的新文件,內容如下:

// lib/src/hero.dart

class Hero {
  final int id;
  String name;
  Hero(this.id, this.name);
  @override
  String toString() => '$id: $name';
}

你定義了一個包含一個構造函數,兩個屬性(idname)和一個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;

接下來,修改模板。現在它顯示的是英雄的idname。修復它,只顯示英雄的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指令會根據一個布爾條件,插入或移除元素。通過把下面的段落添加到模板的底部,我們可以看到實際效果。

// lib/app_component.dart (message)

<p *ngIf="heroes.length > 3">There are many heroes!</p>

不要忘了*ngIf中的前導星號 (*)。它是本語法中不可或缺的一部分。 更多ngIf*的內容,見模板語法ngIf 部分。

雙引號中的模板表達式,*ngIf ="heros.length > 3",看起來就像是 Dart。當組件中的英雄列表有三個以上時,Angular 把這個段落添加到 DOM 中,于是消息顯示了出來。如果有3個或少于3個,Angular 會忽略這個段落,所以就沒有信息顯示。更多信息,見模板語法中的模板表達式部分。

Angular 并不是在顯示和隱藏這條消息,它是在從 DOM 中添加和移除這個段落元素。這會提高性能,特別是在一些大的項目中有條件地包含或排除一大堆帶著很多數據綁定的 HTML 時。

試一下。因為列表中有四個條目,所以消息顯示了出來。回到app_component.dart,從英雄列表中刪除或注釋掉一個元素。瀏覽器刷新后,信息應該不存在了。

總結

現在你學會了如何使用:

  • 帶有雙花括號的插值表達式來顯示一個組件屬性。
  • ngFor 來顯示一列條目。
  • 用一個 Dart 類來為組件描述模型數據并顯示模型的屬性。
  • ngIf 來根據一個布爾表達式有條件的顯示一段HTML。

下一步

用戶輸入

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容