iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
Modern Web

Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站系列 第 15

Day 15 Angular Pipe 與 Directive – 讓模板更聰明

  • 分享至 

  • xImage
  •  

今日目標

  • 認識 Angular 內建 Pipe(格式化輸出)
  • 自訂一個 Pipe(例如:技能名稱轉大寫、描述截斷)
  • 認識 Angular 內建 Directive(ngClass、ngStyle)
  • 自訂一個 Directive(例如:高亮技能卡片)

基礎概念

Pipe(管線)

  • Pipe 可以在模板中用 | 來處理資料。
  • 常見內建 Pipe:
    • date:格式化日期
    • uppercase / lowercase:大小寫轉換
    • currency:數字轉貨幣
    • slice:取部分字串或陣列

範例:

<p>今天是 {{ today | date:'yyyy/MM/dd' }}</p>
<p>金額:{{ 1999.5 | currency:'TWD' }}</p>

Directive(指令)

  • Angular 提供結構指令(改變 DOM 結構,如 ngIfngFor)。
  • 也有屬性指令(改變元素樣式或行為,如 [ngClass][ngStyle])。

範例:

<p [ngClass]="{ 'highlight': isActive }">Hello</p>


實作:Pipe

1) 內建 Pipe(快速上手)

projects.component.html 加上內建 Pipe:

<article class="card" *ngFor="let project of projects; trackBy: trackByTitle">
  <h3>{{ project.title | uppercase }}</h3>
  <p class="muted">{{ project.tech | slice:0:20 }}...</p>
  <p>{{ project.desc }}</p>
</article>

👉 專案標題會全大寫,技術描述只取前 20 個字。


2) 自訂 Pipe:字串截斷

建立一個 Pipe:

ng g pipe pipes/summary

summary.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'summary' })
export class SummaryPipe implements PipeTransform {
  transform(value: string, limit = 30): string {
    if (!value) return '';
    return value.length > limit ? value.substring(0, limit) + '...' : value;
  }
}

使用範例:

<p>{{ project.desc | summary:40 }}</p>

👉 描述超過 40 個字會自動加上 ...


實作:Directive

1) 內建 Directive

skills.component.html 增加 [ngClass],當技能是前端類別就高亮:

<li *ngFor="let s of view; trackBy: trackByName"
    [ngClass]="{ 'highlight': s.category === 'frontend' }">
  {{ s.name }}
</li>

skills.component.scss

.highlight {
  background: #e0f2fe;
  border: 1px solid #38bdf8;
}


2) 自訂 Directive:滑鼠移入高亮

建立 Directive:

ng g directive directives/hoverHighlight

hover-highlight.directive.ts

import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';

@Directive({
  selector: '[appHoverHighlight]'
})
export class HoverHighlightDirective {
  constructor(private el: ElementRef, private renderer: Renderer2) {}

  @HostListener('mouseenter') onEnter() {
    this.renderer.setStyle(this.el.nativeElement, 'background', '#fef9c3');
  }

  @HostListener('mouseleave') onLeave() {
    this.renderer.removeStyle(this.el.nativeElement, 'background');
  }
}

使用範例(在 Skills 清單套用):

<li *ngFor="let s of view; trackBy: trackByName" appHoverHighlight>
  {{ s.name }}
</li>

👉 滑鼠移入技能項目會自動變色。


成果

  • 使用內建 Pipe 讓模板更精簡(uppercase、slice)。
  • 建立了自訂 Pipe(summary),處理字串過長問題。
  • 使用內建 Directive(ngClass)與自訂 Directive(hoverHighlight)強化互動。
  • 模板更乾淨、元件邏輯更單純。

小心踩雷

  1. Pipe 不要濫用在複雜運算
    • ❌ 在 Pipe 裡跑重型計算 → 每次偵測變更都會觸發
    • ✅ Pipe 適合純格式化,重邏輯要放 Service
  2. Directive selector 命名要加前綴
    • 避免和 HTML 原生屬性撞名
    • 推薦習慣用 appXxx
  3. Renderer2 優於直接操作 DOM
    • el.nativeElement.style
    • renderer.setStyle → 更安全,更適合 SSR

下一步(Day 16 預告)

明天我們進入 HttpClient 串接 API 與 RxJS

  • 學會用 Angular 的 HttpClient 呼叫 API
  • 認識 Observable 與 async pipe
  • 把 Projects 從服務中的假資料改為「模擬 API 回傳」

上一篇
Day 14 Angular 巢狀路由與 Lazy Loading – 作品詳情子頁面
系列文
Angular、React、Vue 三框架實戰養成:從零打造高品質前端履歷網站15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言