我一直在测试Angular Elements。基本上,我创建了2个角度元素:一个简单的按钮和一个简单的输入。您可以在此处查看它们:http://kaloyanmanev.com/edo-button.js和http://kaloyanmanev.com/edo-input.js
这两个元素都包括它们自己的polyfill,主要,运行时,脚本和样式,如下所示: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引起的。我尝试将其从元素的polyfills中删除,但随后出现一个错误,即需要zone.js,并且所有元素都不起作用。
那么如何使用这些元素?
*编辑
我从捆绑软件中删除了polyfills,并且将CDN中的zone.js包括在内。尽管如此,仍然出现另一个错误:
ERROR DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "`edo-button`" has already been used with this registry
答案 0 :(得分:0)
您应该为两个组成部分创建一个项目。
他们两个都使用zone.js并覆盖原始的浏览器承诺。这就是为什么出现错误。
有两个选项。
您可以将两个组件都添加到同一模块中。这将导致更大一些的js文件(如果不计入普通情况),而不是仅添加所需的js文件。例如如果该网站只有唯一的按钮,则您不需要输入其他内容。
另一方面,您可以创建js文件,例如edo-button
,edo-input
,edo-button-and-input
。我认为1或2 kB没那么重要。
答案 1 :(得分:0)
您面临的问题是因为 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,组件将按需加载。
答案 2 :(得分:0)
将package.json中的zone.js更新到0.10.3解决了此问题。 [“ zone.js”:“ 0.10.3”]