问题
Im building a small Angular Application with Angular's i18n setup. Everything ist working fine, except for the translations of the url paths and slugs. I tried a possible solution with providing a routing module per language (as described here), but this did not work.
I thought that I could do something like the following, but I can't figure out where to inject LOCALE_ID
:
app-routing.module.ts
import { LOCALE_ID, NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MainComponent } from './main/main.component';
const i18nRoutes = {
de: {
main: 'inhalte',
// ...
},
fr: {
main: 'contenu',
// ...
}
}
const currentLanguage = i18nRoutes[ LOCALE_ID ]; // <-- Apparently not working, since I have to inject LOCALE_ID. But where?
const routes: Routes = [
{
path: '',
redirectTo: currentLanguage.main,
pathMatch: 'full'
},
{
path: currentLanguage.main + '/:key',
component: MainComponent
}
// ...
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Update for clarification
in angular.json
, I set configurations for the building process in each language (taken from here, with a view modifications for 2018)
angular.json
{
// ...
"projects": {
"my-app": {
// ...
"architect": {
"build": {
// ...
"configurations": {
// ...
"de": {
"i18nFile": "src/i18n/de.xliff",
"outputPath": "dist/de",
"i18nFormat": "xlf",
"i18nLocale": "de",
"baseHref": "/de/"
// ...
},
"fr": {
"i18nFile": "src/i18n/fr.xliff",
"outputPath": "dist/fr",
"i18nFormat": "xlf",
"i18nLocale": "fr",
"baseHref": "/fr/",
// ...
}
}
}
}
}
}
For building all apps at once, I then enter npm run buildall
, which executes the following in package.json
:
package.json
{
"name": "my-app",
// ...
"scripts": {
// ...
"buildall": "for lang in de fr;do ng build --configuration=$lang; done"
}
}
which generates all apps in a subdirectory in the dist
folder just fine.
So, to come back to my original question: The provided answer by Exterminator does not fit my needs, since
- I cannot set a fixed locale while bootstrapping
- Injecting
LOCALE_ID
in the constructor is too late since I need the value inapp-routing.module.ts
I hope I explained enough. But maybe I misunderstood something completely. In any case, thanks in advance for any help. I am still learning and I must admit that a few concepts are still blurry to me.
回答1:
I had the same exact problem and this is how I solved it.
I created an app-locale.ts
file that only had one constant that it exports which can then be used for LOCALE_ID provider to set the locale id.
src/app/app-locale.ts
/*
WARNING: This file is to help facilitate the auotmation of the build
process. In order to set the locale during development, change
the value by hand to the target locale. If the file name or
location is changed make sure to update the build scripts
accordingly.
*/
export const APP_LOCALE_ID:string = "es-es";
I used the above constant in my app.module.ts
to provide the LOCALE_ID
.
src/app/app.module.ts
import { LOCALE_ID, NgModule, TRANSLATIONS, TRANSLATIONS_FORMAT } from "@angular/core";
import { APP_LOCALE_ID } from './app-locale';
...
providers: [{
provide: TRANSLATIONS_FORMAT,
useValue: "xlf"
}, {
provide: TRANSLATIONS,
useFactory: (locale) => {
locale = locale || 'en-US';
return require(`raw-loader!../locale/messages.${locale}.xlf`);
},
deps: [LOCALE_ID]
}, {
provide: LOCALE_ID,
useValue: APP_LOCALE_ID
}
],
...
Now I need a small script that would run before the build starts which will set the local id in the file app-locale.ts
. So I wrote this small node script and put it in a separate "scripts" folder.
scripts/set-app-locale.js
const fs = require('fs');
const argv = require('minimist')(process.argv.slice(2));
var version = '0.0.1',
appLocale = "en-US",
appLocaleFile = "./src/app/app-locale.ts",
help = `
Set the static locale for the app.
Usage: node <path>set-app-locale.js [options]
Options:
--version Show version number [boolean]
--help, -h Show help [boolean]
--app-locale Target locale id [string]
--app-locale-file [string]
Path and name of app-locale that contains only one constant which
is a const string that holds the locale value.
[default: "${__dirname}/src/app/app-locale.ts"] `;
var setArgs = function(){
if (argv.version){
console.log(version);
return false;
}
if (argv.h || argv.help){
console.log(help);
return false;
}
appLocale = argv["app-locale"] || appLocale;
appLocaleFile = argv["app-locale-file"] || appLocaleFile;
return true;
}
var setLocale = function(locale){
var fileData =
`/*
WARNING: This file is to help facilitate the automation of the build
process. In order to set the locale during development, change
the value by hand to the target locale. If the file name or
location is changed make sure to update the build scripts
accordingly.
*/
export const APP_LOCALE_ID:string = "${locale}";`;
fs.writeFile(appLocaleFile, fileData, function(err) {
if(err) {
return console.log(err);
}
console.log(`App locale changed to ${locale}`);
});
}
setArgs() && setLocale(appLocale);
Next I would go ahead and change my package.json
to include this to set the locale id.
package.json
....
"config": {"locales": "en-US es-es"},
"scripts": {
...
"i18n-build": "for lang in $npm_package_config_locales; do node ./scripts/set-app-locale.js --app-locale=$lang && ng build --prod --configuration=$lang; done"
}
....
I use xliffmerge
which is part of @ngx-i18nsupport. This helps me avoid overwriting previously extracted and translated strings every time I extract strings.
So now whenever I build the app for all the supported locales, the LOCALE_ID gets set appropriately. I am sure there must be other ways to solve this problem but this is how I solved it.
回答2:
add this to the app.module
providers: [{provide: LOCALE_ID, useValue: 'fr-FR'}]
then call it using the following method where ever you want
import {LOCALE_ID} from '@angular/core';
constructor(@Inject(LOCALE_ID) locale: string){
console.log('locale', locale);
}
also you can use this method
platformBrowserDynamic([{provide: LOCALE_ID, useValue: 'en-EN'}]).bootstrapModule(AppModule, {providers: [{provide: LOCALE_ID, useValue: 'en-EN'}]});
来源:https://stackoverflow.com/questions/52333266/how-to-use-locale-id-in-angular-i18n-router-module