# angular 使用Pipe及Signals建立多國語系 使用Angular開發多語言系網站時,可以藉由Pipe及signals提供動態切換的功能。 ## pipe 建立pipe檔案==TranslatePipe==透運transform來回傳service的資料 src\app\pipes\translate.pipe.ts ```typescript import { Pipe, PipeTransform, inject } from '@angular/core'; import { TranslationService } from '../services/translation.service'; @Pipe({ name: 'translate', pure: false // 允許在語言改變時自動重更新 }) export class TranslatePipe implements PipeTransform { private translationService = inject(TranslationService); transform(value: string): string { return this.translationService.translate(value); } } ``` >pure: false?設定此屬性可確保 Angular 在語言變更時重新執行pipe,防止範本中出現翻譯更新問題。 ## service 建立service檔案,讀取json作為回應的語系,並且透過==translate==帶入語系的key來找出回應object value。 src\app\services\translation.service.ts ```typescript import { Injectable, signal, computed } from '@angular/core'; import * as en from '../../assets/i18n/en.json'; import * as tw from '../../assets/i18n/tw.json'; import * as jp from '../../assets/i18n/jp.json'; @Injectable({ providedIn: 'root' }) export class TranslationService { private language = signal<'tw' | 'en' | 'jp'>('tw'); private translations = computed(() => { switch (true) { case this.language() === 'en': console.log('lang: --en') return en; case this.language() === 'jp': return jp; default: return tw; } }); setLanguage(lang: 'tw' | 'en' | 'jp') { console.log('lang:', lang) this.language.set(lang); } translate(key: string): string { const translations = this.translations() as Record<string, string>; return translations[key] || key; } } ``` ## component 建立component檔案,並且import剛剛所創建的pipe及serviec src\app\components\translation\translation.component.ts ```typescript import { Component, inject, ChangeDetectorRef } from '@angular/core'; import { TranslationService } from '../../services/translation.service'; import { TranslatePipe } from '../../pipes/translate.pipe'; @Component({ selector: 'app-translation', imports: [TranslatePipe], templateUrl: './translation.component.html', styleUrl: './translation.component.css' }) export class TranslationComponent { private translationService = inject(TranslationService); private cdr =inject(ChangeDetectorRef) changeLang(lang: 'tw' | 'en' | 'jp') { this.translationService.setLanguage(lang); this.cdr.detectChanges(); } alertButton(){ alert(this.translationService.translate('WELCOME')); } } ``` 設定component的html,並且顯示多語系及button作為切換 src\app\components\translation\translation.component.html ```typescript <p>translation works!</p> <h1>HELLO:{{ 'HELLO' | translate }}</h1> <p>WELCOME:{{ 'WELCOME' | translate }}</p> <!-- Buttons to change language --> <button (click)="changeLang('tw')">中文</button> <button (click)="changeLang('en')">English</button> <button (click)="changeLang('jp')">日文語</button> <button (click)="alertButton()">alert</button> ``` ## 測試與結論 最後測試run的時候,是否有呈現所屬語系及對應的回應,按下alert也會直接呼叫service轉換回應所屬語系的內容。 ![image](https://hackmd.io/_uploads/B13DlE561l.png) ✅ 這種方法的優點: 🚀 不用http傳輪,完全地端運作 ⚡ 即時語言切換,無網路延遲 📂 直接在專案中進行 JSON 檔案管理 🔧 易於維護和擴充 這種方法具有可擴展性、易於維護,並且有高效能的多語系功能,無需 ngx-translate 等外部元件。 >參考來源: >https://medium.com/@ilenia.scala/angular-multi-language-without-libraries-a-custom-pipe-with-signals-c1c18482fe77 ###### tags:`angular19`,`pipe`,`signals`