@libs-ui/pipes-format-number
v0.2.357-11
Published
> Angular pipe format số theo ngôn ngữ (EN/VI) với phân cách hàng nghìn, số thập phân và kiểm soát số âm.
Readme
@libs-ui/pipes-format-number
Angular pipe format số theo ngôn ngữ (EN/VI) với phân cách hàng nghìn, số thập phân và kiểm soát số âm.
Giới thiệu
LibsUiPipesFormatNumberPipe là một Angular standalone pipe giúp hiển thị số theo chuẩn locale EN hoặc VI. Pipe tự động detect ngôn ngữ từ UtilsCache hoặc nhận ngôn ngữ trực tiếp qua tham số. Bên trong là thin wrapper của hàm viewDataNumberByLanguage từ @libs-ui/utils, vì vậy khi cần dùng trong TypeScript thì gọi thẳng hàm đó mà không cần inject pipe.
Tính năng
- ✅ Phân cách hàng nghìn theo locale: dấu
.cho VI, dấu,cho EN - ✅ Định dạng số thập phân với số chữ số tùy chỉnh (
parseFixed) - ✅ Kiểm soát số âm —
acceptNegativeValue: falsetrả về0thay vì hiển thị số âm - ✅ Tự động detect ngôn ngữ từ
UtilsCachenếu không truyền tham sốlang - ✅ Hỗ trợ truyền ngôn ngữ trực tiếp vào pipe (
'en'hoặc'vi') - ✅ Chấp nhận cả
numbervàstringlàm giá trị đầu vào - ✅ Standalone pipe — import trực tiếp vào component, không cần NgModule
Khi nào sử dụng
- Hiển thị số tiền, giá cả với định dạng phân cách hàng nghìn chuẩn locale
- Format số thập phân theo chuẩn ngôn ngữ (EN:
1,234,567.89— VI:1.234.567,89) - Cần kiểm soát hành vi khi giá trị âm (ẩn số âm, hiển thị 0 thay thế)
- Chuyển đổi giữa định dạng số có dấu phân cách và số thuần trong cùng template
Cài đặt
npm install @libs-ui/pipes-format-numberImport
import { LibsUiPipesFormatNumberPipe } from '@libs-ui/pipes-format-number';
// Dùng trong component
@Component({
standalone: true,
imports: [LibsUiPipesFormatNumberPipe],
// ...
})
export class MyComponent {}Nếu cần dùng trong TypeScript (computed, service), import thẳng hàm utils — không cần inject pipe:
import { viewDataNumberByLanguage } from '@libs-ui/utils';Ví dụ sử dụng
Ví dụ 1 — Format cơ bản (tự động detect ngôn ngữ)
import { Component } from '@angular/core';
import { LibsUiPipesFormatNumberPipe } from '@libs-ui/pipes-format-number';
@Component({
selector: 'app-price-display',
standalone: true,
imports: [LibsUiPipesFormatNumberPipe],
template: `
<!-- Tự động detect ngôn ngữ từ UtilsCache -->
<p>Giá: {{ 1234567 | LibsUiPipesFormatNumberPipe:true:2 }}</p>
<!-- Output VI: 1.234.567 -->
<!-- Output EN: 1,234,567 -->
`,
})
export class PriceDisplayComponent {}Ví dụ 2 — Truyền ngôn ngữ trực tiếp
import { Component } from '@angular/core';
import { LibsUiPipesFormatNumberPipe } from '@libs-ui/pipes-format-number';
@Component({
selector: 'app-price-locale',
standalone: true,
imports: [LibsUiPipesFormatNumberPipe],
template: `
<p>EN: {{ 1234567.89 | LibsUiPipesFormatNumberPipe:true:2:true:false:'en' }}</p>
<!-- Output: 1,234,567.89 -->
<p>VI: {{ 1234567.89 | LibsUiPipesFormatNumberPipe:true:2:true:false:'vi' }}</p>
<!-- Output: 1.234.567,89 -->
`,
})
export class PriceLocaleComponent {}Ví dụ 3 — Kiểm soát số âm
import { Component } from '@angular/core';
import { LibsUiPipesFormatNumberPipe } from '@libs-ui/pipes-format-number';
@Component({
selector: 'app-balance-display',
standalone: true,
imports: [LibsUiPipesFormatNumberPipe],
template: `
<!-- Hiển thị số âm bình thường -->
<p>Số dư: {{ -5000.5 | LibsUiPipesFormatNumberPipe:true:2 }}</p>
<!-- Output VI: -5.000,5 -->
<!-- Ẩn số âm, trả về 0 -->
<p>Số dư tối thiểu: {{ -5000.5 | LibsUiPipesFormatNumberPipe:false:2 }}</p>
<!-- Output: 0 -->
`,
})
export class BalanceDisplayComponent {}Ví dụ 4 — Dùng trong TypeScript (không cần inject pipe)
import { Component, computed, signal } from '@angular/core';
import { viewDataNumberByLanguage } from '@libs-ui/utils';
@Component({
selector: 'app-invoice',
standalone: true,
template: `<p>Tổng tiền: {{ totalFormatted() }}</p>`,
})
export class InvoiceComponent {
private readonly total = signal<number>(9876543.123);
// Dùng thẳng hàm utils trong computed — không inject pipe
protected totalFormatted = computed(() =>
viewDataNumberByLanguage(this.total(), true, 2, true, false, 'vi')
);
// Output: 9.876.543,12
}Ví dụ 5 — Số thập phân với parseFixed
import { Component } from '@angular/core';
import { LibsUiPipesFormatNumberPipe } from '@libs-ui/pipes-format-number';
@Component({
selector: 'app-rate-display',
standalone: true,
imports: [LibsUiPipesFormatNumberPipe],
template: `
<!-- 1 chữ số thập phân (mặc định) -->
<p>{{ 1234.5678 | LibsUiPipesFormatNumberPipe:true:1 }}</p>
<!-- Output VI: 1.234,5 -->
<!-- 3 chữ số thập phân -->
<p>{{ 1234.5678 | LibsUiPipesFormatNumberPipe:true:3 }}</p>
<!-- Output VI: 1.234,567 -->
<!-- Không có thập phân -->
<p>{{ 1234.5678 | LibsUiPipesFormatNumberPipe:true:0 }}</p>
<!-- Output VI: 1.234 -->
`,
})
export class RateDisplayComponent {}Transform (Pipe)
Tên pipe
LibsUiPipesFormatNumberPipeCú pháp
{{ value | LibsUiPipesFormatNumberPipe : acceptNegativeValue }}
{{ value | LibsUiPipesFormatNumberPipe : acceptNegativeValue : parseFixed }}
{{ value | LibsUiPipesFormatNumberPipe : acceptNegativeValue : parseFixed : ignoreFormatSeparator }}
{{ value | LibsUiPipesFormatNumberPipe : acceptNegativeValue : parseFixed : ignoreFormatSeparator : ignoreParseFloat }}
{{ value | LibsUiPipesFormatNumberPipe : acceptNegativeValue : parseFixed : ignoreFormatSeparator : ignoreParseFloat : lang }}Tham số
| Tham số | Type | Bắt buộc | Default | Mô tả | Ví dụ |
|---|---|---|---|---|---|
| value | number \| string | Có | — | Giá trị cần format | 1234567.89 |
| acceptNegativeValue | boolean | Có | — | Cho phép giá trị âm. Nếu false, giá trị âm trả về 0 | true |
| parseFixed | number | Không | 1 | Số chữ số thập phân tối đa | 2 |
| ignoreFormatSeparator | boolean | Không | true | Bỏ qua dấu phân cách có sẵn trong chuỗi đầu vào trước khi format | false |
| ignoreParseFloat | boolean | Không | undefined | Không parse float, giữ nguyên chuỗi thập phân gốc | false |
| lang | string | Không | undefined | Ngôn ngữ format: 'en' hoặc 'vi'. Nếu không truyền, tự động detect từ UtilsCache | 'vi' |
Quy tắc format theo ngôn ngữ
| Ngôn ngữ | Phân cách hàng nghìn | Phân cách thập phân | Ví dụ (1234567.89) |
|---|---|---|---|
| 'en' | , | . | 1,234,567.89 |
| 'vi' | . | , | 1.234.567,89 |
Dùng trong TypeScript (standalone)
import { viewDataNumberByLanguage } from '@libs-ui/utils';
// Tự động detect ngôn ngữ từ UtilsCache
const result = viewDataNumberByLanguage(1234567.89, true, 2);
// Output VI: '1.234.567,89'
// Truyền ngôn ngữ cụ thể
const resultEN = viewDataNumberByLanguage(1234567.89, true, 2, true, false, 'en');
// Output: '1,234,567.89'
const resultVI = viewDataNumberByLanguage(1234567.89, true, 2, true, false, 'vi');
// Output: '1.234.567,89'
// Số âm với acceptNegativeValue = false
const noNegative = viewDataNumberByLanguage(-5000, false, 2);
// Output: '0'Lưu ý quan trọng
⚠️ Thứ tự tham số positional: Pipe dùng positional arguments, không phải named. Muốn truyền lang thì phải truyền đủ cả ignoreFormatSeparator và ignoreParseFloat trước đó: {{ value | LibsUiPipesFormatNumberPipe:true:2:true:false:'vi' }}.
⚠️ acceptNegativeValue là bắt buộc: Tham số này luôn phải được truyền (không có default). Thiếu tham số này pipe sẽ nhận undefined và hành vi không xác định.
⚠️ Detect ngôn ngữ tự động: Khi không truyền lang, pipe gọi UtilsCache.getLang() để detect ngôn ngữ hiện tại của ứng dụng. Đảm bảo UtilsCache đã được khởi tạo với ngôn ngữ đúng trước khi render.
⚠️ Dùng trong TypeScript — không inject pipe: Pipe là thin wrapper. Khi cần format trong .ts (service, computed, resolver), hãy import thẳng viewDataNumberByLanguage từ @libs-ui/utils thay vì inject LibsUiPipesFormatNumberPipe.
⚠️ parseFixed và trailing zeros: parseFixed là số chữ số thập phân tối đa, không phải cố định. Số 1234.5 với parseFixed: 3 có thể cho ra 1.234,5 (không padding thêm 0).
