3

问题是我有很多 HTML 模板,其中包含< script >标签和 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放在哪里?和常数?

4

2 回答 2

2

我推荐 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.

我建议在 Angular 8 组件中升级 AngularJs 组件。就像那样,将来你会趋向于只迁移到 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]
于 2019-07-05T09:05:04.243 回答
2

我建议你使用Web Components

基本上,您必须将 AngularJS 应用程序包装为 Web 组件,然后将其导入您的 Angular 8 应用程序。你最终会得到这样的东西

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

它可以导入到 Angular 8 应用程序的任何组件中。

没有关于如何做到这一点的官方解决方案,但那里有很好的例子。我建议你关注这个:

使用 Web 组件升级:从 ANGULARJS 到 Angular

一旦你在那里向下滚动,直到你看到 将 AngularJS 组件公开为自定义元素

在您设法将 AngularJS 应用程序捆绑为一个 Web 组件后,将整个应用程序放在一个脚本 (main.js) 中,您必须将其复制到您的 Angular 8 应用程序中。

  1. 在您的 Angular 8 应用程序中,创建文件夹assets/web-components/my-angularjs-app
  2. 将您从 AngularJS (main.js) 生成的文件复制到您刚刚创建的文件夹中
  3. 将文件导入angular.json- 将其添加到脚本中: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>
于 2019-07-05T09:23:14.540 回答