2023-03-08 16:45

[Angular] 簡單製作多國語系

我想要用一種簡單而且直覺的方式製作多國語系,想像的用法如下:

user-list.component.html

<h2>{{lang['T_編輯使用者']}}</h2>

<div>
    <p *ngIf="lang.id == 'en'">
    Complicated English description...
    </p>
    <p *ngIf="lang.id == 'tw'">
    複雜的中文描述...
    </p>
</div>

<button type="submit">{{lang['B_儲存']}}</button>

<select [(ngModel)]="lang.id" (change)="lang.change()">
    <option *ngFor="let x of lang.options | keyvalue" [value]="x.key">{{x.value}}</option>
</select>

我希望能使用中文變數,有熟悉的文字可以讓程式看起來親切一點,對於複雜的文字區段也保留彈性,簡單的切換方式,以及狀態保留,讓 browser 紀錄選擇的語系。

user-list.component.ts

import { Component, OnInit } from '@angular/core';
import { AppLang } from 'app/app.lang';

@Component({
    selector: 'app-user-list',
    templateUrl: './user-list.component.html'
})
export class UserListComponent implements OnInit {

    /** 狀態選項 */
    statusItems = {
        'y': this.lang.E_啟用,
        'n': this.lang.E_停用,
    };

    constructor(
        public lang: AppLang
    ) { }

    ngOnInit() {
        let msg = String(this.lang.M_請填寫_0_的刻度值).format(3);
    }
}

已經想好使用情境了,接著來就是完成實作了!

app.lang.ts

import { Injectable } from '@angular/core';

/** 多國語言 */
@Injectable()
export class AppLang {

    constructor() {
        let _: any = {}; /* 語系字典 */
        let self: any = this;
        let names: string[] = Object.keys(this).filter(n => !'id,options,change'.includes(n));

        /* 重組語系字典 */
        Object.keys(this.options).forEach(id => {
            _[id] = {};
            names.forEach(name => _[id][name] = self[name][id]);
        });

        /* 複寫 change */
        this.change = function () {
            if (!_[this.id]) { this.id = 'tw'; }

            Object.assign(this, _[this.id]);
            localStorage['langId'] = this.id;
        }

        this.change ();
    }


    id: string = localStorage['langId'];

    options: any = {
        tw: '中文',
        en: 'English',
    };

    /** 變更語言 */
    change() { }



    /*=[ Title ]=============================================*/

    T_編輯使用者: any = {
        tw: '編輯使用者',
        en: 'Edit User',
    };
    //...

    /*=[ Field ]=============================================*/

    F_名稱: any = {
        tw: '名稱',
        en: 'Name',
    };
    //...

    /*=[ Button ]=============================================*/

    B_儲存: any = {
        tw: '儲存',
        en: 'Save',
    };
    //...


    /*=[ Enum ]=============================================*/

    E_啟用: any = {
        tw: '啟用',
        en: 'Enable',
    };
    E_停用: any = {
        tw: '停用',
        en: 'Disable',
    };
    //...


    /*=[ Message ]=============================================*/

    M_請填寫_0_的刻度值: any = {
        tw: '請填寫 {0} 的刻度值',
        en: 'Please fill in the scale value of {0}.',
    };
    //...

}

app.module.ts 配置

//...
import { AppLang } from 'app/app.lang';

@NgModule({
    declarations: [
        //...
    ],
    imports: [
        //...
    ],
    providers: [
        //...
        AppLang
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

0 回應: