跨域加载外置transaction-element.js后组件未渲染无报错问题咨询
问题原因排查
你遇到的问题不是跨域直接导致的:你已经为script标签添加了crossorigin属性且资源加载成功,说明跨域资源共享配置本身是正常的。无报错不渲染的核心原因通常是以下几种:
- Angular未配置自定义元素识别规则,默认无法识别非Angular实现的自定义元素标签
- 自定义元素加载时机晚于模板渲染时机:你异步加载web component对应的js文件时,Angular已经提前渲染了
<transaction-element>标签,此时该标签还未被注册为自定义元素,浏览器会将其作为普通未知标签处理,不会触发渲染逻辑 - web component内部使用了相对路径引用静态资源,在localhost:4200域下请求时出现404,导致组件初始化失败
解决方法
- 首先在使用该自定义元素的对应Angular模块中添加
CUSTOM_ELEMENTS_SCHEMA,示例如下:
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; @NgModule({ // ... 其他模块配置 schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class YourModule { }
- 调整自定义元素加载与渲染的时机,确保js加载完成、自定义元素注册后再渲染标签:
- 给script标签添加onload回调,设置加载完成标记
- 模板中使用
*ngIf控制自定义元素的渲染时机
代码示例:
// 组件类中新增加载状态标记 isTransactionElementReady = false; addTransactionElement() { this.http.get<any>('../transaction/transactionUrl').subscribe((res) => { const link = this.renderer.createElement('link'); link.rel = 'stylesheet'; link.href = 'http://localhost:8083/elements/assets/fonts/webadk-icon-font.css'; this.renderer.appendChild(this.document.head, link); const script = this.renderer.createElement('script'); script.type = 'text/javascript'; this.renderer.setAttribute(script, 'crossorigin', 'true'); script.src = 'http://localhost:8083/transaction-element.js'; // 新增加载完成回调 script.onload = () => { // 确认自定义元素注册完成 customElements.whenDefined('transaction-element').then(() => { this.isTransactionElementReady = true; this.cdr.detectChanges(); // 手动触发变更检测 }) }; this.renderer.appendChild(this.document.head, script); }); }
模板调整:
<ng-container *ngIf="isTransactionElementReady"> <transaction-element [businessLine]="transactionInfo.businessLine" [theme]="transactionTheme" ></transaction-element> </ng-container>
注:尽量使用Angular的属性绑定语法[]而非插值语法{{}}传递属性,避免非字符串类型的值传递异常
- 检查web component打包配置,将所有内部引用的静态资源(图片、字体、子chunk等)路径改为指向localhost:8083的绝对路径,避免在4200域下请求资源失败
内容的提问来源于stack exchange,提问作者CCNA
相关产品推荐
相关产品推荐

