【问题标题】:Angular Elements Output not working in IE11Angular Elements 输出在 IE11 中不起作用
【发布时间】:2019-01-21 16:01:16
【问题描述】:

我尝试让 Angular Elements 在 IE11 中工作。 我的自定义元素(简单按钮)已经显示并且输入绑定按预期工作,但输出绑定没有。

在 IE 11 中单击我的自定义元素按钮会导致错误:

对象不支持此操作

到目前为止我做了什么:

  1. 删除使用 ng add @angular/elements 添加的自定义元素的 polyfill(无法在 IE 中正常工作)
  2. 将所有 Angular 包更新为 7.2.1

  3. 将以下 polyfillls 添加到 polyfills.ts

import 'core-js/shim'
import '@webcomponents/shadydom/shadydom.min.js';
import '@webcomponents/custom-elements/src/native-shim';
import '@webcomponents/custom-elements/custom-elements.min';
  1. 手动引导模块

  2. ng build --output-hashing=none 并将所有生成的文件打包到 btn-element.js 中,与 http-server 一起提供以进行本地测试(请参阅下面的 index.html)。

我错过了特定的 polyfill 还是我做错了什么?还是现在还不可能?

app.module.ts:

@NgModule({
  declarations: [ ButtonComponent ],
  imports: [ BrowserModule ],
  entryComponents: [ ButtonComponent ]
})
export class AppModule {
  constructor(private injector: Injector) {
    const customBtn = createCustomElement(ButtonComponent, { injector });
    customElements.define('app-btn', customBtn);
  }
  ngDoBootstrap() { }
}

button.component.ts:

@Component({
  template: `<button (click)="handleClick()">{{ label }}</button>`,
  encapsulation: ViewEncapsulation.ShadowDom
})
export class ButtonComponent {
  @Input() label;
  @Output() myaction = new EventEmitter<number>();
  private clicksCt: number = 0;

  constructor() { }

  handleClick() {
    this.clicksCt++;
    this.myaction.emit(this.clicksCt);
  }
}

index.html

<html lang="en">
<head>  
  [...]
  <script type="text/javascript" src="btn-element.js"></script>
</head>
<body>
<app-btn label="Button Text"></app-btn>

<script>
    var button = document.querySelector('app-btn');
    button.addEventListener('myaction', function (event) {
         console.log('action emitted: ' + event.detail);          <!-- not working! -->
     });
     setTimeout(function () {
         button.label = 'Async value change happened...'   <!-- working! -->
     }, 2000);
    }
</script>
</body>
</html>

我也试过&lt;app-btn label="Button Text" (myaction)="test($event)"&gt;&lt;/app-btn&gt;,但没有成功。

编辑: Minimal Example

在 IE 11 中似乎无法正常工作。要重现我的结果并看到 StackBitz 在 Chrome 中运行时的效果,请按照以下步骤操作:

  1. 复制到本地机器
  2. 运行npm install
  3. 运行 npm run build &amp;&amp; npm run package:win(适用于 Windows)
  4. index.html 和生成的btn-element.js 提供http-server

【问题讨论】:

  • 无法根据您的 polyfills.ts 重现您的问题,它会显示模块未找到错误(即使我安装了 webcomponents)。那么,您能否像Minimal, Complete, and Verifiable example 一样发布足够的代码来重现该问题。否则,我会尝试使用 @angular/elements 创建自定义元素,并将显示结果。
  • 另外,我建议你可以使用F12开发者工具检查btn-element.js文件是否加载成功,是否包含一些js错误。
  • 感谢您抽出宝贵时间。我想通过检查我是否忘记发布相关的代码,我发现了错误。可悲的是,当我想重复验证它的步骤时,我无法检查它,因为如果我打开开发工具,IE 就会一直崩溃。因此,如果您还打包它们并且它们在 IE 11 中工作,我会非常感兴趣您是如何创建 CE 的。
  • @ZhiLv-MSFT 还是添加了 StackBitz example
  • @jowey 你明白了吗?我有同样的问题

标签: angular internet-explorer-11 custom-element angular-elements


【解决方案1】:

official document我们可以看到:

目前,许多浏览器都原生支持最近开发的自定义元素 Web 平台功能。其他浏览器的支持正在等待或计划中。

我也尝试测试一下官方文档包含的demo,在Chrome浏览器下运行良好,在IE/Edge浏览器下不行。

在IE浏览器会显示语法错误,如下:

因此,正如官方文档所说,他们正在努力实现自定义元素以支持 IE/Edge 浏览器。

【讨论】:

  • 为所有感兴趣的人添加了一个 StackBitz,因为通过将 TS 目标类型设置为 ES5 并添加一些 polyfill,我似乎走得更远了。我的组件显示和输入绑定工作,但正如标题所示,输出绑定不工作。
  • 您在文档中的哪些地方发现它们支持 IE ?原生 IE 支持实际上是不可能的,因为 IE 需要 ES5。
  • 在旧版浏览器中有很多自定义元素的 polyfills。即使是谷歌支持的(LitElement),所以如果 Angular 在旧版浏览器中不支持“Angular Elements”,我会感到惊讶。
  • 文档中确实说它应该适用于 ES5 浏览器 angular.io/guide/elements#browser-support-for-custom-elements
【解决方案2】:

我在一个小项目中工作。以下是需要完成的检查清单。

要在 IE11 中运行 Angular Elements,您需要:

  • 将 Angular 应用程序编译为 ES5 和生产标志
  • 包含 Polymer 项目 webcomponentsjs/custom-elements-es5-adapter.js 以使 ES5 语法与现代浏览器中的 customElements API 一起使用
  • 包含 Polymer 项目 web 组件 polyfill webcomponentsjs/webcomponents-loader.js https://www.webcomponents.org/polyfills/
  • 确保它们与 Angular 代码的顺序正确
<script type="text/javascript" src="dist/AngularComponentTest/runtime.js"></script>
<script type="text/javascript" src="dist/AngularComponentTest/polyfills.js"></script>
<script src="webcomponentsjs/custom-elements-es5-adapter.js"></script>
<script src="webcomponentsjs/webcomponents-loader.js"></script>
<script type="text/javascript" src="dist/AngularComponentTest/main.js"></script></body>
  • 要加载一个简单的组件,您不需要启用 polyfills.ts 中的任何“浏览器 Polyfill”
  • 不要包含custom-elements-es5-adapter.js 使用任何意味着它被转译的东西,例如Angular 构建配置的脚本或 polyfill.ts

使用 Angular 9 执行上述操作为我提供了运行 Angular Element 并从中发出事件所需的一切。

等我稍微整理一下之后,我会发布一个示例应用程序。

【讨论】:

  • 在没有 zone.js 的情况下这也可以工作吗?您能否也请发布示例应用程序。
  • 有例子可以发吗?
猜你喜欢
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 2020-03-21
  • 2015-08-27
  • 1970-01-01
相关资源
最近更新 更多