javascript

Angular 5 (или 4): даунгрейдим компонент для использования в AngularJS

  • воскресенье, 10 декабря 2017 г. в 03:12:19
https://habrahabr.ru/post/344272/
  • JavaScript
  • Angular


На днях возникла весьма необычная задача: понадобилось узнать, как компоненты из Angular использовать в AngularJS. Вроде и задача на пять минут, т.к. интернет пестрит схожими примерами, да и в документации вроде бы что-то есть. Но на деле оказалось, что не все так солнечно и решение вопроса заняло куда больше времени. Вобщем, счастливым саппортерам легаси кода и просто angular-извращенцам посвящается

Сперва традиционная рубрика TL DR: Хорош графоманить, пример в студию

Ну а теперь можно графоманить.

Начну с того, что документация у ангулара крайне плоха. Так было в первой версии, так продолжается до сих пор. Традиция, вобщем. Поэтому за основу для даунгрейда брал эту статью. Теперь сам код:

Внимание! Для полноты ощущений ниже я привожу no-typescript пример angular компонента. Весь дальнейший код будет выдержан в таком стиле.

Итак, собственно, компонент:

let HelloComponent = function () {
};

HelloComponent.annotations = [
  new ng.core.Component({
    selector: 'hello-world',
    template: 'Hello World!'
  })
];

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

Добавляем код AppModule:

class AppModule {
}

AppModule.prototype.ngDoBootstrap = function() {
  // do nothing
};

AppModule.annotations = [
  new ng.core.NgModule({
    declarations: [HelloComponent],
    imports: [ng.upgrade.static.UpgradeModule, ng.platformBrowser.BrowserModule],
    entryComponents: [HelloComponent]
  })
];

Про ngDoBootstrap можно почерпнуть из статьи, которую я указывал выше, как основу для даунгрейда.

Так, модуль сделали, теперь надо подключить все это в AngularJS:

angular.module("app", [])
.directive("helloWorld", ng.upgrade.static.downgradeComponent({component: HelloComponent}))

После чего добавить загрузку самого Angular:

ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(AppModule).then(platformRef => {
  const upgrade = platformRef.injector.get(ng.upgrade.static.UpgradeModule);
  upgrade.bootstrap(document.body, ['app'], { strictDi: true });
});

Но и этот пример не работает, говорит что-то насчет
Unknown provider: $$angularLazyModuleRefProvider


В конечном итоге оказывается, что просто напросто нужно передать $$UpgradeModule в качестве зависимости модуля AngularJS.

P.S. решил написать статью из соображений, что подобное может понадобиться кому-то еще. Буду рад, если смог кому-то помочь.

P.P.S. Еще ссылки: пишем на angular в es5