0

我一直在测试 Angular Elements。基本上我创建了 2 个角度元素:一个简单的按钮和一个简单的输入。你可以在这里查看它们:http: //kaloyanmanev.com/edo-button.jshttp://kaloyanmanev.com/edo-input.js

这两个元素都包括它们自己的 polyfills、main、runtime、脚本和样式,如下所示:https ://blog.angulartraining.com/tutorial-how-to-create-custom-angular-elements-55aea29d80c5

我正在尝试将它们包含在这样的 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>

基本上发生的事情是我得到了 2 个按钮,但它们之间没有输入,当然还有那个讨厌的错误:

Error: Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.
The most likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise API is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)

当我单独使用脚本时,它可以工作......如果我将它们都包含在内,它不会。我研究了一下,但找不到任何解决方案。真的没有办法在一页中使用 2 个角度元素吗?

这个问题很可能是由 Angular 使用的 zone.js 引起的。我尝试将其从元素的 polyfill 中删除,但随后出现错误,指出 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
4

3 回答 3

0

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

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

有两种选择。

  1. 您可以将这两个组件添加到同一个模块中。这将导致一些更大的 js 文件(如果不计算常见的东西)而不是只添加所需的 js 文件。例如。如果该站点有唯一的按钮,您将不需要额外的输入。

  2. 另一方面,您可以创建 js 文件,如edo-button, edo-input, edo-button-and-input. 我不认为 1 或 2 kB 有那么重要。

于 2019-11-14T23:08:29.527 回答
0

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

参考:https ://github.com/angular/angular/issues/11650

于 2020-05-04T08:21:45.613 回答
-1

您面临的问题是因为Zone.js被多次加载,因此覆盖了 Promise。

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

ng add ngx-build-plus

添加后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,您的组件将按应有的方式加载。

于 2019-11-22T07:19:45.133 回答