Имах два проблема. Първо, ние не използваме SystemJS. Второ, използвахме UpgradeAdapter за стартиране на ъглово 1 + 2 хибридно приложение.

Докато всички ръководства на Angular използват SystemJS, angular-cli използва Webpack и това беше избраният от нас инструмент. Така че getTranslationsWithSystemJS трябва да бъде пренаписано като нещо, което използва webpack, завършвайки с това:

[code lang=”javascript”]
function getTranslationFilesWithWebpack(locale: string) {
return System.import('./assets/locale/messages.' + locale + '.xlf')

[/code]

Не е толкова лошо, а? Но също така изисква поддръжка от webpack, така че в webpack.config.js трябваше да добавя правило за обработка на xlf файлове:

[code lang=”javascript”]
function webpackConfig(options) {
return {
devtool: false,
resolve: {
extensions: ['.ts' , '.js']
},
контекст: __dirname,
запис: {
основен: './src/main'
},
изход: {
път: 'dist',
име на файл: '[име].bundle.js',
sourceMapFilename: '[име].map',
chunkFilename: ' [име].chunk.js',
publicPath: '/static/teachers-site/dist/'
},
модул: {
правила: [
/* правилата за html, css и ts са премахнати за краткост */
{
тест: /\.xlf/,
зареждащ инструмент: 'raw'
},
{
тест: /\.json|\.map$/,
зареждане: 'ignore-loader'
}
]
}
};< br />
module.exports = webpackConfig;
[/code]

Има един ключов компонент:

[code lang=”javascript”]
{
test: /\.xlf/,
loader: ‘raw’
},
[/code]

Това правило казва на webpack, че всички xlf файлове, които среща, трябва да бъдат вмъкнати като необработен текст. Използването на System.import('path...' + filename) казва на webpack да създаде точка на разделяне за файлове в path и ще им позволи да бъдат импортирани по заявка като обещание. (Тази функция е нова от Webpack 2.)

В крайна сметка получаваме нещо подобно в нашата dist директория:

  • main.bundle.jsсъдържащ нашия уебсайт
  • n.chunk.js, където n започва от 0 и се брои за всеки xlf, който имаме.

(Забележка: вероятно трябва да намерим начин да преименуваме парчетата)

Трябваше да направя още две важни, но фини промени:

Първо, трябваше да добавя publicPath: "/static/teachers-site/dist" към изходната секция. Без това нашето уеб приложение щеше да се опита да зареди частите от https://host/teachers-site/0.chunk.js и щяхме да получим объркваща страница за грешка 404, която ще изпрати времето за изпълнение крещяща среда.

Второ, трябваше да уведомя webpack как да обработва други файлове, които може да намери. Оказва се, че когато webpack намери System.import извикване, той анализира всеки проектен файл, който може да бъде възможна резолюция, включително конфигурации, карта и други неща.

Но как се прави хибрид?

Когато нашият проект започна, нашият код на хибридно приложение изглеждаше почти така:

[code lang=”javascript”]
// ТОВА НЕ РАБОТИ!!!
// app.module.ts
import { NgModule, forwardRef } from '@angular/core' ;
импортирайте { BrowserModule } от '@angular/platform-browser';
импортирайте { UpgradeAdapter } от '@angular/upgrade';
импортирайте { AppComponent } от './app.component ';
импортиране на {SharedModule} от “./shared/shared.module”;

експортиране на const upgradeAdapter = нов UpgradeAdapter(
forwardRef(() =› AppModule ));

декларирайте var angular: any;
angular
.module(‘rootModule’)
.directive(‘testAngularTwo’,
upgradeAdapter.downgradeNg2Component(AppComponent));

@NgModule({
импортира: [BrowserModule, SharedModule],
декларации: [AppComponent],
bootstrap: [AppComponent]
})
експортира клас AppModule{}

// main.ts
import ‘./polyfills.ts’;

import { upgradeAdapter } from ‘./app/app.module’;
деклариране на променлив документ: произволен;
upgradeAdapter.bootstrap(document, [‘rootModule’]);
[/code]

Просто не можах да разбера как да предам доставчиците на превод към функцията за стартиране на angular 2! Потърсих документите и за моя голяма изненада всички говореха някакви UpgradeModule неща. Много объркващо.

Оказва се, че в Angular 2.2.1 механизмът за надграждане е напълно ревизиран. Или поне публичния му API. Така че надстроих до 2.2.1 и внедрих отново механизма за надграждане, използвайки новите насоки:

[код lang=”javascript”]
// app.module.ts
импортиране на {NgModule} от “@angular/core”;
импортиране на {BrowserModule} от “@angular/platform- браузър”;
импортиране на {AppComponent} от “./app.component”;
импортиране на {UpgradeModule} от “@angular/upgrade/src/aot/upgrade_module”;
импортиране на {downgradeComponent} от “@angular/upgrade/src/aot/downgrade_component”;

@NgModule({
импортира: [
BrowserModule,
UpgradeModule,
],
декларации: [AppComponent],
entryComponents: [AppComponent]
})
клас за експортиране AppModule {
ngDoBootstrap() {}
}

декларирайте var angular: any;
angular
.module('slateClient')
.directive('testAngularTwo', downgradeComponent({
component: AppComponent
})) ;

// main.ts
импортиране на “./polyfills.ts”;
импортиране на {AppModule} от “./app/app.module”;
импортиране на {getTranslationProviders} от “./i18n -providers”;
импортиране на {platformBrowserDynamic} от “@angular/platform-browser-dynamic”;
импортиране на {UpgradeModule} от “@angular/upgrade/src/aot/upgrade_module”;

декларирайте променлив документ: произволен;
декларирайте променлива конзола: произволен;
getTranslationProviders().then(доставчици =› {
const options = {доставчици};
return platformBrowserDynamic(). bootstrapModule(AppModule, options);
})
.then(ref =› {
const upgrade = ref.injector.get(UpgradeModule) as UpgradeModule;
upgrade.bootstrap( document.body, ['slateClient'], {strictDi: true});
})
.catch(console.log.bind(console, “Bootstrap Failed: “))
[ /код]

А-ха! Най-накрая проработи!

Но какво става?

В app.module.ts използвах UpgradeModule като един от моите модули за импортиране и също премахнах секцията bootstrap: [AppComponent]. Тази последна част е важна! Нашето приложение всъщност се зарежда от Angular 2, извиквайки Angular 1, който на свой ред използва компоненти на Angular 2, така че Angular 2 не трябва да зарежда нито един компонент сам! Вместо това трябва да поставим компонентите си в entryComponents.

В main.ts просто питаме за доставчиците на превод, след което (верижно обещания, вижте моята публикация за обещания) зареждаме Angular 2 както обикновено. Този процес на стартиране също връща обещание, така че ние се свързваме с него, за да стартираме Angular 1, използвайки UpgradeModule, който инжектирахме в нашия AppModule.

И накрая, забележете, че .catch(console.log.bind(console, "Bootstrap Failed: ")) в края на main.ts. Това се оказа изключително ценно, тъй като се опитах да разбера защо не мога да стана ъглов за стартиране.

И така, ето го! Надявам се, че ще намерите това за полезно и ме уведомете, ако намерите още по-добър начин за включване на преводи.