简体   繁体   中英

How to prevent web component from loading until template is filled in Angular

I'm using a web component in my angular app. I am using angular attribute bindings to dynamically fill my web component: https://angular.io/guide/attribute-binding

When I hardcode the values for my web component attributes, it works fine. However, when I dynamically bind the attributes, I run into issues.

What seems to be happening is the template loads, then the authVariable is set to the auth-token attribute once the component loads. The web component I am using throws an error when the template loads before the component loads. When the template is then filled with the authVariable, the web component doesn't recover from the error state.

The component I am using does have a default value for authVariable (I'm not doing an async call to get a value for authVariable).

My question is: What is the easiest way to have angular only load a filled version of the template?

This works fine

<web-component
  auth-token="<AUTH_TOKEN>"
>
</web-component>

This doesn't work

<web-component
[attr.auth-token]="authVariable"
>
</web-component>

This is probably a bug with the web component itself. It should be able to detect changes to attributes with the attributeChangedCallback method. However, if you need to work around this issue, you would need to use outerHTML to insert the markup yourself to be evaluated all at once instead of when Angular feels like setting the attributes. Because you'll need to use bypassSecurityTrustHtml to get Angular to parse the non-trivial markup, you need to be confident that the template string you pass in has no security flaws (like interpolating user input), otherwise you'd be opening yourself up to XSS attacks.

// my.component.ts
import {DomSanitizer, SafeHtml} from '@angular/platform-browser';

@Component({…})
class MyComponent {
  private readonly authVariable = '…';
  protected readonly webComponent: SafeHtml;

  constructor(private readonly sanitized: DomSanitizer) {
    this.webComponent = this.sanitized.bypassSecurityTrustHtml(`
      <web-component auth-token="${this.authVariable}">
      </web-component>
    `);
  }
}
<!-- my.component.html -->
<template [outerHTML]="webComponent"></template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM