第 4 天 英雄有偶包怎麽办|*ngFor、JsonPipe、Angular Material、Mat-Card、Mat-Button

前情提要

昨天我们已经成功地使用 HttpClient 发送 Http 请求,从 mock db 取得了英雄资料,并将资料列印在 console 里。今天我们要进一步在画面上显示资料,并且加上 Angular Material 的元件,优化 app 画面表现。

006

(现在,我们要召唤英灵们...)

我们不是已经召唤出来了吗,他们在 console 里躺得好好的呢。

(他们可是英灵,人家是有偶像包袱的,嫌你丑,不想被召唤。)

话要说清楚啊,你应该是说这个 app 都没样式画面丑吧?

(总之就是你自己得好好打理打理。)

你是说好好处理 app 画面吧!我发现你说话越来越省略我很困扰。

(快去打理吧。)

使用 *ngFor 显示英雄资料

首先,我们先使用 Angular 提供的结构指令 *ngFor 来显示阵列资料。在 hero-list.component.html 中输入:

<pre *ngFor="let hero of heroList">
    {{ hero | json }}
</pre>

这是一个很快可以将物件资料呈现在画面上的写法,简单说明这些语法提供的效果:

  • *ngFor: 这是 Angular 的结构性指令,能够依照阵列资料的数量,将挂载此指令以下(含)的 HTML 标签依照阵列资料的数量重复显示出来。
  • JsonPipe: 把一个值转换成 JSON 字串格式。在除错时很有用。
  • pre:HTML 提供的 <pre> 标签,会将标签中的资料依原格式显示,这会让物件资料的排版更好地阅读

上面的程序码输出的结果如下,我在开发时很常使用它们来确认取得的资料:
https://ithelp.ithome.com.tw/upload/images/20210919/201283956k1b4jgvfN.png

将资料放到画面上後,接着我们就要使用 Angular Material 元件来改善画面体验。

安装 Angular Material

不得不说,现在要在专案中添加 Angular Material 简直太容易了,只要进入专案目录执行:

ng add @angular/material

它会询问几个设定配置问题,我一样都是选择预设值(Enter 键连发)。

接着马上来试试看 Angular Material 提供给我们的元件,稍微逛了一下文件,作为展示英雄资讯,觉得可以让每位英雄的资讯都用一个卡片来呈现。那我们就来试试看吧!

将文件中的范例 Copy Paste 到 hero-list.component.html 中,并使用 *ngFor 放上英雄资料:

  <mat-card class="hero-item" *ngFor="let hero of heroList">
    <mat-card-header>
      <div mat-card-avatar class="example-header-image"></div>
      <mat-card-title>{{ hero.name }}</mat-card-title>
      <mat-card-subtitle>Dog Breed</mat-card-subtitle>
    </mat-card-header>
    <img mat-card-image src="https://material.angular.io/assets/img/examples/shiba2.jpg" alt="Photo of a Shiba Inu">
    <mat-card-content>
      <p>
        The Shiba Inu is the smallest of the six original and distinct spitz breeds of dog from Japan.
        A small, agile dog that copes very well with mountainous terrain, the Shiba Inu was originally
        bred for hunting.
      </p>
    </mat-card-content>
    <mat-card-actions>
      <button mat-button>LIKE</button>
      <button mat-button>SHARE</button>
    </mat-card-actions>
  </mat-card>

首先,Angular Material 是将不同的元件封装成不同的 module,所以我们在使用之前,需要先在 module 档汇入对应的 Angular Material Module,所以我们打开 app.module.ts,在 imports 阵列中加入 MatCardModule

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

import { MatCardModule } from '@angular/material/card';

import { AppComponent } from './app.component';
import { HeroListComponent } from './hero-list/hero-list.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  declarations: [
    AppComponent,
    HeroListComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    MatCardModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

可以看到,目前我们并没有那麽多资料需要显示(subtitle、description),因此我们只是在 title 的资料显示栏位,使用 Angular 的文字插值(interpolation),也就是两个大括弧 {{ hero.name }} 来将资料显示在画面上。目前画面会这样呈现:

https://ithelp.ithome.com.tw/upload/images/20210919/20128395p1VdtZM9FX.png

我们很快就会发现几个问题:

  • 吕布变狗了!...这不是问题,每位英雄都变狗了,那是因为现阶段我们没有提供给他们图片,这里显示的 Angular Material 预设的狗狗。
  • 一个狗狗就占满整个版面。这是样式问题,所以我们等等会写一些 CSS 来优化它们。
  • 这个按钮看起来很阳春,Angular Material 文件上的按钮比较有质感,可是我们是直接 Copy 文件上的范例程序码欸,怎麽会这样?

针对最後一个问题,这是因为 Angular Material 的文件 Mat-Card 提供的范例程序码就使用了 Mat-Button 提供的功能。目前,我们并没有在 AppModule 汇入 MatButtonModule,所以我们的按钮看起来比较没质感。让我们来汇入它:

(略)

import { MatCardModule } from '@angular/material/card';
import { MatButtonModule } from '@angular/material/button';

(略)

@NgModule({
  (略)
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
    MatCardModule,
    MatButtonModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

之後我们在打开 hero-list.component.html 将它的外层加上一个 <div class="hero-container"> 标签:

<div class="hero-container">
  <mat-card class="hero-item" *ngFor="let hero of heroList">
    (略)
  </mat-card>
</div>

接着,hero-list.component.css 添加一些样式:

.hero-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.hero-item {
  flex-basis: 300px;
}

这样英雄列表就会如下呈现啦:

https://ithelp.ithome.com.tw/upload/images/20210919/20128395rkBJYypI34.png

就把人类存亡的命运交给他们吧>///////////<


<<:  Day19 测试写起乃 - 撰写Cucumber

>>:  Day13 线性回归实作

30天轻松学会unity自制游戏-安装unity

首先工欲善其事,必先利其器,制作游戏有很多好用的工具。 选择一种适合自己的开始,如已有确认过要开发的...

GPU程序设计(3) -- 矩阵运算

前言 GPU卡原来是针对游戏开发及显示加速的设计的,後来才扩散至挖矿、深度学习...等其他领域,而游...

尚气与十环传奇

尚气与十环传奇在线观看 漫威影业荣誉出品史诗冒险《尚气与十环传奇》,结合前所未见的震撼性动作、令人惊...

Day 18:「极速开发」- Vitawind

「闪电 + 疾风的组合吗? 不错不错!」 既然我们之前都说了要用 Vue + Tailwind 来...

【Day 4_ Arm Mali GPU家族究竟是何方神圣_上篇】

前几篇文章中提到Arm与游戏的关系时,总是会提到Arm Mali系列,光是去年,Arm在全球的合作夥...