首页 > 解决方案 > 同一页面上相同 Angular 自定义元素的多个副本

问题描述

我正在 Angular 13 中编写一个简单的自定义元素,通常包装在另一个应用程序中,该应用程序使用createCustomElement然后customElements.define将其注册到浏览器中并创建单个 JS 包。

一切都很好,直到我在同一页面上放置相同自定义元素的 2 个副本。

他们一样分享一切;例如,StoreService即使组件是两个,一个简单组件也只会创建一次。

更糟糕的是,我担心会与同一页面上的其他不同自定义元素发生冲突,比如 services 或 nrgx/store,可能基于服务名称或 store reducer key,我不知道。

有没有办法完全隔离用 Angular 编写的自定义元素,这样我们就可以确保它的行为正常,无论它使用的环境是什么?

你可以在这里找到完整的例子:https ://github.com/autozoom/multiple-elements1

只需运行npm run start:shell, 去 localhost:4200 并打开控制台。

即使外壳程序有自定义元素的 2 个副本,您也会看到AppModule和仅创建一次,因此服务内部状态在 2 个副本之间共享。StoreServiceAppComponent

非常感谢。

标签: angularweb-componentcustom-elementangular-elements

解决方案


这里的“问题”是如何提供 StoreService。

@Injectable({
  providedIn: 'root',
})

providedIn: 'root' 表示该服务在使用时在应用程序级注入器提供一次

更多信息:https ://angular.io/api/core/Injectable

如果您想完全隔离您的角度元素,您可以选择在组件级别提供服务。

对于这个用例,您必须从服务的 @Injectable 装饰器中删除 providedIn 属性

@Injectable()
export class StoreService 

并使用 ShowComponent 的 @Component 装饰器中的 providedIn 属性:

  //...
  providers: [StoreService],
})
export class ShowComponent

现在,每次实例化 ShowComponent 时,都会提供 StoreService 的一个实例。

您可以通过在 StoreService 的构造函数中添加一条日志语句来验证这一点,如下所示:

在此处输入图像描述


推荐阅读