Как добавить этот HTML-шаблон AngularJS в мой проект Angular 8 - PullRequest
3 голосов
/ 05 июля 2019

Проблема в том, что у меня есть много HTML-шаблонов, которые включают теги с кодом AngularJS в них. Мой текущий проект использует Angular 8, и одна его важная часть состоит в основном в том, чтобы использовать все шаблоны AngularJS, которые у меня есть в этом новом проекте, и выполнять как можно меньше работы (из-за того, что в будущем другие пользователи должны будут возможность добавлять новые шаблоны в проект).

Я должен иметь возможность добавить эти шаблоны HTML AngularJS в мой текущий проект. Для этого я использую ngUpgrade, но он вводит в заблуждение, и я не смог этого добиться.

Вот один из шаблонов, максимально упрощенных для этого вопроса:

HTML

    <body>
        <script>
            angular.module('myApp', [])
                .controller('myController', function ($scope, $timeout) {   
                $scope.local = 'es'; 
                BigFunction($scope, $timeout);
            });

            var texts = {
                title: {
                en: 'A simple title',
            };
            // other constanst go here

            function BigFunction(scope, timeout) {
                scope.texts = texts;
                scope.$watch('content', function(end, ini){
                    // some logic when 'content' changes
                }, true);
            // more logic
            }
        <script>
        <div>
            <!-- Lots of tags using ng-bind and other AngularJS tools -->
        </div>
    </body>

Я должен интегрировать его, касаясь его как можно меньше. Я не знаю, следует ли мне отделить логику сценария от HTML или я могу импортировать его, как он есть сейчас, и работать. Учтите, что у меня нет опыта работы с AngularJS, я разработчик для Angular 2+.

Если мне нужно отделить логику от шаблона, куда мне поместить angular.module ? А константы?

Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 05 июля 2019

Я бы предложил вам использовать Веб-компоненты

По сути, вам придется обернуть приложение AngularJS в виде веб-компонента, а затем импортировать его в приложение Angular 8. Вы бы в конечном итоге что-то вроде этого

<my-angularjs-app></my-angularjs-app>

Он может быть импортирован в любой компонент приложения Angular 8.

Официального решения о том, как это сделать, не существует, но есть хорошие примеры. Я бы предложил вам следовать этому:

ОБНОВЛЕНИЕ С ВЕБ-КОМПОНЕНТАМИ: ОТ АНГУЛЯРНЫХ К УГЛОВЫМ

Как только вы окажетесь там, прокрутите вниз, пока не увидите Предоставление компонентов AngularJS в качестве пользовательских элементов

После того, как вам удастся связать приложение AngularJS как веб-компонент, имея все приложение в одном скрипте (main.js), вам придется скопировать его в ваше приложение Angular 8.

  1. В вашем приложении Angular 8 создайте папку assets / web-components / my-angularjs-app
  2. Скопируйте файл, созданный вами из AngularJS (main.js), в папку, которую вы только что создали
  3. Импорт файла в angular.json - Добавьте это в scripts : assets/web-components/my-angularjs-app/main.js
  4. Ваше приложение AngularJS теперь импортировано, но есть еще одна вещь, которую мы должны сделать, прежде чем вы сможете использовать его в своих компонентах. Вы должны сообщить Angular, что будут некоторые селекторы, о которых Angular может не знать. Для этого перейдите на ваш app.module.ts и добавьте schemas: [CUSTOM_ELEMENTS_SCHEMA]
  5. Теперь вы можете использовать ваше приложение AngularJS где угодно, используя заявленный вами селектор (эта часть находится в ссылке, которую я разместил). <my-angularjs-app></my-angularjs-app>
2 голосов
/ 05 июля 2019

Я рекомендую ng-book, в ней есть полная глава о гибридных приложениях. Обратите внимание, что UpgradeAdapter в книге устарел. Но многие концепции остаются в силе.

NgUpgrade является официальным пакетом, чтобы делать то, что вы хотите.

Первое, что вы должны сделать, это поместить скрипт в нужный файл. И не в HTML. Тогда вы можете сделать серьезное кодирование.

Вы должны следовать документу NgUpgrade, чтобы запустить 2 приложения. https://angular.io/guide/upgrade#bootstrapping-hybrid-applications

вам нужен один загрузчик для AngularJS:

angular.bootstrap(document.body, ['heroApp'], { strictDi: true });

И один загрузчик для Angular 8:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

platformBrowserDynamic().bootstrapModule(AppModule);

Вы заметите, что NgModule имеет опорную линию к AngularJs.

Код, который они дают, предназначен для компиляции JIT.

Производственная сборка в компиляции AOT будет выглядеть следующим образом:

import { enableProdMode } from '@angular/core';
import { platformBrowser } from '@angular/platform-browser';

const { AppModuleNgFactory } = require('../aot/src/app/AppModule.ngfactory');

enableProdMode();
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);

-

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

У вас есть 2 варианта.

inject Angular 8 components in ANgular JS directives
inject Angular JS directives in ANgular 8 components.

Я рекомендую обновить компоненты ANgularJs внутри компонентов Angular 8. Как и в будущем, вы сходитесь к переходу только на Angular 8.

Для копирования каждого компонента AngularJS в компонент Angular 8 потребуется определенная работа.

Чтобы сократить объем работы, запустите Angular JS как есть. И поместите директивы Angular 8 вне шаблонов AngularJS.

<div id="angularjs-root"></div>
<div my-unaltereted-angular8-component></div>

Может быть, я ошибаюсь, и вы не можете поставить их отдельно. Но стоит попробовать.

Сам я динамически внедряю элементы DOM из Angular8 в приложение JQuery. Но вы не можете сделать это в AngularJS, поскольку он имеет жизненный цикл для всех узлов. Однако, с некоторой осторожностью, удаляя визуализацию обнаружения изменений для узла, огромное дерево узлов из Angular 8 может быть вставлено в шаблон шаблона ANgularJs, и это без понижения.

Это то, что я использую.

  addComponentToElement({ component, element }: { component: any, element: any }) {
    // Create a component reference from the component
    const componentRef = this.componentFactoryResolver
      .resolveComponentFactory(component)
      .create(this.injector);

    // Attach component to the appRef so that it's inside the ng component tree
    this.appRef.attachView(componentRef.hostView);

    // Get DOM element from component
    const domElem = (componentRef.hostView as EmbeddedViewRef<any>)
      .rootNodes[0] as HTMLElement;

    // Append DOM element to the body
    element.appendChild(domElem);

    // detect changes
    componentRef.changeDetectorRef.detectChanges();
  }

В AppModule потребуется добавить каждый компонент внутри entryComponents:

  entryComponents: [ InjectedCOmponent1m InjectedCOmponent2]
...