На этапе разработки мы будем использовать systemjs для асинхронной загрузки наших ресурсов. Следующий пример представляет собой модификацию файла system.config.js официального руководства по Angular 2.

(function(global) {
  // map tells the System loader where to look for things
  var map = {
    'app':                        'app', // 'dist',
    'rxjs':                       'node_modules/rxjs',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    '@angular':                   'node_modules/@angular',
    'modules':                    'node_modules/',
    'ng2-translate':              'node_modules/ng2-translate'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js', defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { defaultExtension: 'js' },
    'modules':                    { defaultExtension: 'js' },
    'ng2-translate':              { main: 'ng2-translate.js' },
  };
  var packageNames = [
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/http',
    '@angular/platform-browser',
    '@angular/platform-browser-dynamic',
    '@angular/router-deprecated',
    '@angular/testing',
    '@angular/upgrade',
  ];
  // add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
  packageNames.forEach(function(pkgName) {
    packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
  });
  var config = {
    format: 'register',
    map: map,
    packages: packages,
    defaultExtension: 'js',
    baseURL: 'app-ng2/'
  };
  System.config(config);
})(this);

Интересным моментом здесь является поддержка модуля ng2-translate, который является преемником поставщика перевода angular-translate. Автор angular-translate теперь работает с командой Google Angular, чтобы интегрировать тему перевода непосредственно в официальный стек angular.

Теперь мы подготовили все наши конфигурационные файлы и можем приступить к реальной работе.

Интеграция с угловым 2

Во-первых, мы изменим index.html с нашими зависимостями, а также вставим наш файл javascript начальной загрузки Angular 2.

...
<!-- build:js vendors2.min.js -->
<script src="app-ng2/node_modules/es6-shim/es6-shim.min.js"></script>
<script src="app-ng2/node_modules/zone.js/dist/zone.js"></script>
<script src="app-ng2/node_modules/reflect-metadata/Reflect.js"></script>
<script src="app-ng2/node_modules/systemjs/dist/system.src.js"></script>
<script src="app-ng2/systemjs.config.js"></script>
<!-- endbuild -->
<!-- build:js app2.min.js -->
<script src="app-ng2/bootapp.js"></script>
<!-- endbuild -->
...

ES6-shim и reflect-metadata — это мерцания для совместимости ES6 со старыми браузерами. Оба модуля необходимы для ssystemjs.
Zone.js реализует зоны. Зона — это контекст выполнения, который сохраняется для асинхронных задач.
systemjs.config.js — это конфигурация SystemJS, которую мы создали ранее.
bootapp.js содержит загрузочный модуль приложения systemjs.

(function() {
'use strict';
angular.element(window).ready(function() {
    System.import('app').then(null, console.error.bind(console));
});
})();

Когда мы вставляем загрузчик systemjs в отдельный файл, мы можем просто заменить этот файл файлом пакета в процессе сборки релиза.

В файле systemjs.config.js у нас есть псевдоним app, связанный с файлом main.js.

...
var packages = {
  'app':      { main: 'main.js', defaultExtension: 'js' },...

Поэтому, когда браузер открывает index.html, systemjs автоматически загружает файл main.js.

import { upgrade } from './upgrade_adapter';
import { HTTP_PROVIDERS, Http } from '@angular/http';
import { provide } from '@angular/core';
import { LocationStrategy, HashLocationStrategy } from '@angular/common';
import 'rxjs/add/operator/map';
import { TranslateService, TranslateStaticLoader, TranslateLoader } from 'ng2-translate';
import { SettingsAbout } from './settings/about/settings.about.component';
upgrade.addProvider(HTTP_PROVIDERS);
upgrade.addProvider(TranslateService);
upgrade.addProvider(provide(LocationStrategy, {useClass: HashLocationStrategy}));
upgrade.addProvider(provide(TranslateLoader, {
    useFactory: (http: Http) => new TranslateStaticLoader(http, '/cheetah/api/list/bmcockpits/translate?locale=', ''),
    deps: [Http]
}));
upgrade.upgradeNg1Provider('AuthService');
/// <reference path="../typings/angular/angular.d.ts" />
angular.module('app.hmc.settings').directive('settingsAbout', <angular.IDirectiveFactory>upgrade.downgradeNg2Component(SettingsAbout));
upgrade.bootstrap(document.body, ['app']);

Как обычно в начале файла ts идут импорты. Здесь интересен импорт модуля обновления. Содержание модуля upgrade_adapter.ts следующее:

import { UpgradeAdapter } from '@angular/upgrade';
export const upgrade = new UpgradeAdapter();

Здесь мы создаем адаптер постоянного обновления. Это означает, что адаптер является синглтоном.

UpgradeAdapter — это модуль из angular 2, который используется для непрерывного обновления мира angular 1 до angular 2 и взаимодействия между ними. С помощью адаптера обновления мы можем не только обновить директивы, провайдеры и т. д. angular 1, но и понизить версию компонентов и сервисов angular 2 для использования в angular 1.

main.js содержит в импорте помимо общих требований ng2 также наш первый компонент ng2 SettingsAbout. После этого регистрируем провайдеров. Поскольку нам нужна наша служба аутентификации ng2 для аутентификации и авторизации, мы обновили службу AuthService ng1, просто позвонив

upgrade.upgradeNg1Provider('AuthService');

и наш компонент SettingsAbout ng2 мы также очень просто понизили.

angular.module('app.hmc.settings').directive('settingsAbout', <angular.IDirectiveFactory>upgrade.downgradeNg2Component(SettingsAbout));

Конец файла загружает нашу интегрированную систему ng1-ng2.

upgrade.bootstrap(document.body, ['app']);

SettingsAbout является обычным компонентом ng2 и использует ng1 AuthService, обновленный до ng2; никакой магии.

import {Component, Inject} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import {TranslateService, TranslatePipe} from 'ng2-translate';
@Component({
    selector: 'settings-about',
    templateUrl: 'app-ng2/app/settings/about/about.html',
    pipes: [TranslatePipe]
})
export class SettingsAbout {
constructor(private http: Http, @Inject('AuthService') private authService: any, private translateService: TranslateService) {
        translateService.setDefaultLang('en');
        translateService.use(language);
        this.getAboutInfo();
...
    };
    private getAboutInfo() {
...
    };
...
}

Когда у нас будет готовый компонент ng2 SettingsAbout, мы можем использовать его в качестве директивы для элемента ng1. В приведенном ниже примере мы используем подход взаимодействия компонентов ng1.5 с ui-router. Но вместо компонента ng1.5 мы используем компонент ng2 пониженной версии.

$stateProvider
    .state('app.settings.about', {
        url: '/About',
        data: {
            authorizedRoles: 
...
        },
        views: {
            '[email protected]': {
                template: '<settings-about />'
            }
        }
    });

Итак, теперь у нас есть первый компонент ng2, используемый внутри проекта ng1, и вы можете по тому же шаблону расширить это взаимодействие.

Пожалуйста, продолжайте с Преобразование Angular 2, система построения.