Merge pull request #4868 from abpframework/feat/4867

Added support for mapping of culture name to Angular locale file name
pull/4882/head
Erol Arkat 5 years ago committed by GitHub
commit eedd1b9413
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -193,6 +193,32 @@ import { Component } from '@angular/core';
export class AppComponent {}
```
## Mapping of Culture Name to Angular Locale File Name
Some of the culture names defined in .NET do not match Angular locales. In such cases, the Angular app throws an error like below at runtime:
![locale-error](./images/locale-error.png)
If you see an error like this, you should pass the `cultureNameToLocaleFileNameMapping` property like below to CoreModule's forRoot static method.
```js
// app.module.ts
@NgModule({
imports: [
// other imports
CoreModule.forRoot({
// other options
cultureNameToLocaleFileNameMapping: {
"DotnetCultureName": "AngularLocaleFileName",
"pt-BR": "pt" // example
}
})
//...
```
See [all locale files in Angular](https://github.com/angular/angular/tree/master/packages/common/locales).
## See Also
@ -200,4 +226,4 @@ export class AppComponent {}
## What's Next?
* [Permission Management](./Permission-Management.md)
* [Permission Management](./Permission-Management.md)

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

@ -34,7 +34,7 @@ import { ConfigState } from './states/config.state';
import { ProfileState } from './states/profile.state';
import { ReplaceableComponentsState } from './states/replaceable-components.state';
import { SessionState } from './states/session.state';
import { CORE_OPTIONS } from './tokens/options.token';
import { CORE_OPTIONS, coreOptionsFactory } from './tokens/options.token';
import { noop } from './utils/common-utils';
import './utils/date-extensions';
import { getInitialData, localeInitializer, configureOAuth } from './utils/initial-utils';
@ -171,9 +171,14 @@ export class CoreModule {
useValue: { environment: options.environment },
},
{
provide: CORE_OPTIONS,
provide: 'CORE_OPTIONS',
useValue: options,
},
{
provide: CORE_OPTIONS,
useFactory: coreOptionsFactory,
deps: ['CORE_OPTIONS'],
},
{
provide: HTTP_INTERCEPTORS,
useClass: ApiInterceptor,

@ -9,6 +9,7 @@ export namespace ABP {
environment: Partial<Config.Environment>;
skipGetAppConfiguration?: boolean;
sendNullsAsQueryParam?: boolean;
cultureNameToLocaleFileNameMapping?: Dictionary<string>;
}
export interface Test {

@ -8,6 +8,7 @@ import { Config } from '../models/config';
import { ConfigState } from '../states/config.state';
import { registerLocale } from '../utils/initial-utils';
import { createLocalizer, createLocalizerWithFallback } from '../utils/localization-utils';
import { CORE_OPTIONS } from '../tokens/options.token';
type ShouldReuseRoute = (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) => boolean;
@ -44,11 +45,12 @@ export class LocalizationService {
registerLocale(locale: string) {
const router = this.injector.get(Router);
const { cultureNameToLocaleFileNameMapping: localeNameMap } = this.injector.get(CORE_OPTIONS);
const { shouldReuseRoute } = router.routeReuseStrategy;
router.routeReuseStrategy.shouldReuseRoute = () => false;
router.navigated = false;
return registerLocale(locale).then(() => {
return registerLocale(locale, localeNameMap).then(() => {
this.ngZone.run(async () => {
await router.navigateByUrl(router.url).catch(noop);
router.routeReuseStrategy.shouldReuseRoute = shouldReuseRoute;

@ -1,4 +1,15 @@
import { InjectionToken } from '@angular/core';
import { ABP } from '../models/common';
import differentLocales from '../constants/different-locales';
export const CORE_OPTIONS = new InjectionToken<ABP.Root>('CORE_OPTIONS');
export function coreOptionsFactory({
cultureNameToLocaleFileNameMapping: localeNameMap = {},
...options
}: ABP.Root) {
return {
...options,
cultureNameToLocaleFileNameMapping: { ...differentLocales, ...localeNameMap },
} as ABP.Root;
}

@ -4,7 +4,6 @@ import { Store } from '@ngxs/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { tap } from 'rxjs/operators';
import { GetAppConfiguration } from '../actions/config.actions';
import differentLocales from '../constants/different-locales';
import { ABP } from '../models/common';
import { ConfigState } from '../states/config.state';
import { CORE_OPTIONS } from '../tokens/options.token';
@ -45,22 +44,25 @@ function checkAccessToken(store: Store, injector: Injector) {
export function localeInitializer(injector: Injector) {
const fn = () => {
const store: Store = injector.get(Store);
const options = injector.get(CORE_OPTIONS);
const lang = store.selectSnapshot(state => state.SessionState.language) || 'en';
return new Promise((resolve, reject) => {
registerLocale(lang).then(() => resolve('resolved'), reject);
registerLocale(lang, options.cultureNameToLocaleFileNameMapping).then(
() => resolve('resolved'),
reject,
);
});
};
return fn;
}
export function registerLocale(locale: string) {
export function registerLocale(locale: string, localeNameMap: ABP.Dictionary<string>) {
return import(
/* webpackInclude: /(af|ar|am|ar-SA|as|az-Latn|be|bg|bn-BD|bn-IN|bs|ca|ca-ES-VALENCIA|cs|cy|da|de|de|el|en-GB|en|es|en|es-US|es-MX|et|eu|fa|fi|en|fr|fr|fr-CA|ga|gd|gl|gu|ha|he|hi|hr|hu|hy|id|ig|is|it|it|ja|ka|kk|km|kn|ko|kok|en|en|lb|lt|lv|en|mk|ml|mn|mr|ms|mt|nb|ne|nl|nl-BE|nn|en|or|pa|pa-Arab|pl|en|pt|pt-PT|en|en|ro|ru|rw|pa-Arab|si|sk|sl|sq|sr-Cyrl-BA|sr-Cyrl|sr-Latn|sv|sw|ta|te|tg|th|ti|tk|tn|tr|tt|ug|uk|ur|uz-Latn|vi|wo|xh|yo|zh-Hans|zh-Hant|zu)\.js$/ */
/* webpackChunkName: "[request]"*/
`@angular/common/locales/${differentLocales[locale] || locale}.js`
/* webpackChunkName: "_locale-[request]"*/
`@angular/common/locales/${localeNameMap[locale] || locale}.js`
).then(module => {
registerLocaleData(module.default);
});

Loading…
Cancel
Save