Я пытаюсь использовать официальные инструменты интернационализации Angular с универсальным Angular. До сих пор я мог перевести визуализацию на стороне клиента, используя следующую процедуру (благодаря этому ответу qaru.site/info/231126/...):
Я добавляю атрибуты "i18n", как указано в документации в моих шаблонах:
./src/+ app/about/about.component.html:
<h1 i18n="H1 of the about component">About</h1>
...
Затем я запускаю:
./node_modules/.bin/ng-xi18n
для создания базового файла messages.xlf.
Затем я копирую этот файл для каждой локали, которую хочу поддерживать как " сообщения. [locale].xlf" в папке "locale". Когда я готов, я создаю " сообщения. [Locale].ts" для каждого файла xlf, содержащего экспортированную строку его содержимого:
./locale/messages.fr.ts:
// TRANSLATION_FR is only for "messages.fr.ts" of course.
// I would create a TRANSLATION_ES const inside "messages.es.ts" for spanish for example.
export const TRANSLATION_FR: string = `<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="004b222ff9ef9dd4771b777950ca1d0e4cd4348a" datatype="html">
<source>About</source>
<target>A propos</target>
<note priority="1" from="description">H1 of the about component</note>
</trans-unit>
</body>
</file>
</xliff>
`;
Наконец, мой файл client.ts выглядит следующим образом:
./src/client.ts:
[...]
// i18n
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';
import { TRANSLATION_FR } from '../locale/messages.fr';
import { MainModule } from './browser.module';
export const platformRef = platformUniversalDynamic();
// on document ready bootstrap Angular 2
export function main() {
return platformRef.bootstrapModule(MainModule, {
providers: [
{provide: TRANSLATIONS, useValue: TRANSLATION_FR},
{provide: TRANSLATIONS_FORMAT, useValue: "xlf"},
{provide: LOCALE_ID, useValue: 'fr'}
]
});
}
bootloader(main);
Это работает и делает приложение "клиентская сторона" работающим, как ожидалось. " О" заменяется на " Предложение". НО, потому что Angular универсальный предварительный рендеринг страницы со стороны сервера, используя выражение, текст не переводится до тех пор, пока не будет завершена загрузка на стороне клиента.
Итак, когда вы впервые заходите на страницу, вы видите " О" в течение примерно 1 секунды, прежде чем клиентская сторона начнет заменять ее " Предложение".
Решение кажется очевидным, просто запустите службу перевода на стороне сервера! Но я не знаю, как это сделать.
Мой server.ts выглядит следующим образом:
./ЦСИ/server.ts
[...]
// i18n
import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';
import { TRANSLATION_FR } from '../locale/messages.fr';
const app = express();
const ROOT = path.join(path.resolve(__dirname, '..', 'dist'));
// Express View
app.engine('.html', createEngine({
ngModule: MainModule,
providers: [
/**
* HERE IS THE IMPORTANT PART.
* I tried to declare providers but it has no effect.
*/
{provide: TRANSLATIONS, useValue: TRANSLATION_FR},
{provide: TRANSLATIONS_FORMAT, useValue: "xlf"},
{provide: LOCALE_ID, useValue: 'fr'}
]
}));
app.set('port', process.env.PORT || 3000);
app.set('views', ROOT);
app.set('view engine', 'html');
[...]
function ngApp(req, res) {
res.render('index', {
req,
res,
preboot: false,
baseUrl: '/',
requestUrl: req.originalUrl,
originUrl: `http://localhost:${ app.get('port') }`
});
}
app.get('*', ngApp);
// Server
let server = app.listen(app.get('port'), () => {
console.log(`Listening on: http://localhost:${server.address().port}`);
});
У меня нет прямого доступа к методу bootstrapModule, например, на стороне клиента. Клавиша провайдеров на объекте параметра createEngine уже существует на исходном сервере .ts.
Что мне не хватает?