На днях возникла весьма необычная задача: понадобилось узнать, как компоненты из 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

Комментарии (13)


  1. Stearis
    09.12.2017 12:18

    Выражаю огромный респект за терпение тем людям, которые поддерживают приложения на устаревших фреймворках. Я, однажды попробовав Angular 2+, не захотел бы больше трогать AngularJS без видимой на то причины (а такая только одна, ИМХО — требование заказчика).

    что документация у ангулара крайне плоха. Так было в первой версии, так продолжается до сих пор


    Тут я с Вами не согласен. Angular.io вкупе со статьями из Медиума, Хабра и бесчисленных мелких бложиков способны творить чудеса.


    1. ivanuzzo Автор
      09.12.2017 12:19

      хорошая документация — это когда не приходится после ее чтения лезть на stack overflow или искать решение на хабре и бесчисленных мелких бложиках


      1. alexs0ff
        10.12.2017 12:43

        Это где это такая библитека/фреймворк о котором не задавали бы вопросы на SO?


        1. ivanuzzo Автор
          11.12.2017 00:06

          документация ангулара настолько неудачная, что задавать вопросы приходится постоянно. У ангулара достаточно высокий порог вхождения, много чего в доках не прописано, может потому, что и так понятно (разработчикам гугла). Чтоб далеко не ходить, взять хотя бы усложненный интерфейс директив в angularjs или задачу, описанную в этой статье. Или вот еще, например, достаточно объективная статья на тему сложности ангулара.


          1. alexs0ff
            11.12.2017 08:05
            -1

            , взять хотя бы усложненный интерфейс

            Это по angular js. У ангулара 4 все по другому.
            например, достаточно объективная статья на тему

            Это объективная статья на тему того, как автор не осилил ангулар.

            PS
            На мой вопрос, Вы так и не ответили.


            1. ivanuzzo Автор
              11.12.2017 11:08

              не ответил, потому что вопрос риторический, да и статья посвящена ангулару, а не другим библиотекам и фреймворкам.

              P.S. в чем выражается то, что автор той статьи не осилил ангулар?


              1. alexs0ff
                11.12.2017 11:21
                -1

                Да нет, потому что какая бы документация не была, всегда возникают вопросы использования или обхода багов в том или ином фреймворке.


                1. ivanuzzo Автор
                  11.12.2017 11:38
                  +1

                  Мой вопрос не об этом. Вы написали:

                  Это объективная статья на тему того, как автор не осилил ангулар.

                  В чем выражается то, что автор той статьи не осилил ангулар?


                  1. alexs0ff
                    11.12.2017 11:58

                    Вот хотя бы нарезка.

                    временем становится очень приятно воспринимать любые данные, пусть даже не совсем подходящие для Observable, как единую шину

                    RxJs позволяет абстрагировать не от самих данных, а от источников данных.
                    Я реактивную разработку пробовал еще в далеком 2011 году на backende, тогда она не пошла, а вот спустя несколько лет, набравшись опыта — взлетела как по маслу.

                    Сам по себе TypeScript идеально подходит для написания максимально строгого кода

                    Опять путаем строгую/нестрогую типизацию со статической/динамической.
                    И вообще ликбез

                    Иммутабельность это здорово, но если вы думаете, что большинство классов в Angular являются таковыми, то это вовсе не так.

                    Почему именно все классы должны быть иммутабельны? Вообще-то иммутабельность это не изобретение команды ангулар, это такой принцип работы с типами и к Angular/Typescript отношения не имеет.

                    Angular вообще не имеет толкового разбора и описания Observable и того, как с ними работать.

                    А ничего, что RxJS это совершенно другая библиотека и используется отдельно от Angular и зачем копипастить документацию с одного места в другое — я не понимаю.

                    И т.д. и тп.


                    1. ivanuzzo Автор
                      11.12.2017 12:05

                      Приведенные вами примеры больше относятся к rxjs и typescript, чем к ангулару.


                      1. alexs0ff
                        11.12.2017 12:18

                        RxJs это часть Angular, хотя и может использоваться отдельно.
                        Некоторые остальные недочеты я автору указывал в комментах ниже. Например,Validators.compose. Оказалось, автор просто перед написанием статьи не удосужился посмотреть последнюю документацию.

                        Для себя сделал вывод. Angular просто идеален, когда разработчик пришел к нему из BackEnda(Java,C# и т.д.). Если же основная работа в последнее время велась на FrontEnde — javascript, jquery и т.д. очень трудно перестроить образ мышления.


                        1. ivanuzzo Автор
                          11.12.2017 21:42

                          тот факт, что rxjs используется в ангулар не означает, что rxjs — часть ангулара. Это отдельная библиотека для javascript. Частью ангулара можно назвать его пакеты типа angular/core или angular/common.

                          Я просмотрел комментарии той статьи, но в итоге вы меня не убедили в том, что автор не осилил ангулар. Ваше замечание автору, хоть и важно, но все же это единичный случай, который значит лишь одно — доки ангулара таки обновляются, что не может не радовать.


    1. VolCh
      09.12.2017 17:46

      Формально говоря, фреймворки типа первого ангуляра устаревшими не являются, даже если проигнорировать что последний коммит два дня назад в мастер сделан. Устаревшими являются те, которые без бубна на современных окружениях не запустить.