Angular 角度元素错误:Zone.js检测到ZoneAwarePromise

Angular 角度元素错误:Zone.js检测到ZoneAwarePromise,angular,web-component,angular-elements,zone.js,micro-frontend,Angular,Web Component,Angular Elements,Zone.js,Micro Frontend,我一直在测试角度元素。基本上我创建了两个角度元素:一个简单的按钮和一个简单的输入。你可以在这里查看:和 这两个元素都包含它们自己的多边形填充、主元素、运行时元素、脚本和样式,如下所示: 我正在尝试将这些内容包含在HTML文件中,如下所示: <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <base href="/"> <meta name="

我一直在测试角度元素。基本上我创建了两个角度元素:一个简单的按钮和一个简单的输入。你可以在这里查看:和

这两个元素都包含它们自己的多边形填充、主元素、运行时元素、脚本和样式,如下所示:

我正在尝试将这些内容包含在HTML文件中,如下所示:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
  <edo-button></edo-button>
  <edo-input></edo-input>
  <edo-button></edo-button>
</body>
<script src="http://kaloyanmanev.com/edo-button.js"></script>
<script src="http://kaloyanmanev.com/edo-input.js"></script>
</html>
当我单独使用脚本时,它可以工作。。。如果我把它们都包括进去,那就不算了。我研究了一下,但没有找到任何解决办法。说真的,没有办法在一页中使用两个角度元素

问题很可能是由Angular使用的zone.js引起的。我尝试将其从元素的多边形填充中删除,但随后出现了一个错误,即zone.js是必需的,并且所有元素都不起作用

那么如何使用这些元素呢

*编辑

我从包中删除了polyfill,并从CDN中包含zone.js。不过,还有另一个错误:

ERROR DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "`edo-button`" has already been used with this registry

您应该为两个组件创建一个项目

他们都在使用zone.js并覆盖原始浏览器承诺。这就是你出错的原因

有两种选择

  • 您可以将这两个组件添加到同一个模块中。这将导致一些更大的js文件(如果普通的东西不算),而不是只添加所需的js文件。例如。如果网站只有一个按钮,你就不需要额外的输入了

  • 另一方面,您可以创建js文件,如
    edo按钮
    edo输入
    edo按钮和输入
    。我认为1或2 kB没有那么重要


  • 您面临的问题是因为Zone.js被多次加载,从而覆盖了承诺

    这个问题的解决方案在于web组件的构建过程。基本上,您需要分离出库文件和web组件逻辑并分别加载它们

    ng添加ngx构建增强版

    添加
    ngx build plus
    后,您需要在app.module.ts文件中进行一些更改

    import { BrowserModule } from '@angular/platform-browser';
    import {DoBootstrap, Injector, NgModule} from '@angular/core';
    
    import { AppComponent } from './app.component';
    import {createCustomElement} from '@angular/elements';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule
      ],
      providers: [],
      // bootstrap: [AppComponent],
      entryComponents: [
        AppComponent
      ]
    })
    export class AppModule implements DoBootstrap {
      constructor(private injector: Injector) {
    
      }
    
      ngDoBootstrap() {
        const el = createCustomElement(AppComponent, { injector: this.injector });
        customElements.define('phoenix-wc-wiki-ngx', el);
      }
    }
    
    运行以下命令

    ng build--prod--output hashing none--single bundle true


    现在,您可以在
    dist
    文件夹中找到可以在应用程序中使用的分离文件。您只需包含zone.js一次,您的组件就会按原样加载。

    将package.json中的zone.js更新为0.10.3解决了此问题。[“zone.js”:“0.10.3”]


    参考资料:

    我不想为这些文件制作另一个角度项目。我编辑了答案。你不需要做更多的项目。对于这两个组件,一个项目就足够了。将要用作元素的两个组件添加到
    app.module.ts
    中。一个JS文件作为答案中的第一个选项就足够了。但我希望能够将它们作为两个独立的组件使用。然后第二个选项就是你的选择。这需要更多的时间去做。我不认为你不使用的其他组件会破坏你的应用程序的性能。这对我来说也很有效。以前在我的webapp中使用了0.9.3和angular 8,以及一个单独的web组件包。
    import { BrowserModule } from '@angular/platform-browser';
    import {DoBootstrap, Injector, NgModule} from '@angular/core';
    
    import { AppComponent } from './app.component';
    import {createCustomElement} from '@angular/elements';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule
      ],
      providers: [],
      // bootstrap: [AppComponent],
      entryComponents: [
        AppComponent
      ]
    })
    export class AppModule implements DoBootstrap {
      constructor(private injector: Injector) {
    
      }
    
      ngDoBootstrap() {
        const el = createCustomElement(AppComponent, { injector: this.injector });
        customElements.define('phoenix-wc-wiki-ngx', el);
      }
    }