Angular поддерживает i18n и динамическое
переключение локалей через встроенный механизм LOCALE_ID и
библиотеку @angular/common. Динамическая загрузка локалей
позволяет изменять язык приложения без перезагрузки страницы.
Локали импортируются из @angular/common/locales и
регистрируются через функцию registerLocaleData():
import { registerLocaleData } from '@angular/common';
import localeRu from '@angular/common/locales/ru';
import localeEn from '@angular/common/locales/en';
registerLocaleData(localeRu, 'ru');
registerLocaleData(localeEn, 'en');
Для динамического изменения локали используется провайдер
LOCALE_ID с фабрикой:
providers: [
{
provide: LOCALE_ID,
useFactory: (localeService: LocaleService) => localeService.currentLocale,
deps: [LocaleService]
}
]
LocaleService управляет текущей локалью приложения и
уведомляет компоненты об изменениях через
BehaviorSubject:
@Injectable({ providedIn: 'root' })
export class LocaleService {
private localeSubject = new BehaviorSubject<string>('en');
currentLocale$ = this.localeSubject.asObservable();
get currentLocale(): string {
return this.localeSubject.value;
}
setLocale(locale: string) {
this.localeSubject.next(locale);
}
}
После регистрации локали Angular автоматически применяет её при
использовании пайпов DatePipe, CurrencyPipe,
DecimalPipe:
<p>{{ today | date:'fullDate' }}</p>
<p>{{ amount | currency:'USD':'symbol' }}</p>
При изменении локали через LocaleService все пайпы
автоматически начинают использовать новую локаль при следующем
обновлении данных.
Для оптимизации можно загружать локали динамически через
import():
async setLocale(locale: string) {
const localeModule = await import(`@angular/common/locales/${locale}.mjs`);
registerLocaleData(localeModule.default, locale);
this.localeSubject.next(locale);
}
Такой подход уменьшает размер начального бандла и позволяет добавлять новые языки без изменения основной сборки.
Компоненты подписываются на изменения локали через
currentLocale$ и обновляют отображение:
this.localeService.currentLocale$.subscribe(locale => {
this.refreshUI();
});
Это обеспечивает полную поддержку runtime-переключения языков без перезагрузки приложения.