Angular-Dynamic-Hooks / ngx-dynamic-hooks

Automatically insert live Angular components into dynamic strings (based on their selector or any pattern of your choice) and render the result in the DOM.
MIT License
116 stars 6 forks source link

Self-closing component tags are not properly supported #46

Open dar-clgo opened 1 week ago

dar-clgo commented 1 week ago

Example: <component [input]="context"/><component2 [input]="context"/> Renders as: <component [input]="context"><component2 [input]="context"></component2></component> When it should render as: <component [input]="context"></component><component2 [input]="context"></component2>

They both get rendered, but one becomes the child of the other

MTobisch commented 1 week ago

Hm, I can probably see about adding support for self-closing components.

The reason it doesn't work right now as that the default selector hook parser processes the content after it has already been rendered as HTML and picks out the component tags from there. Unfortunately, because self-closing tags are not valid HTML and rather a trick of Angular templates, they are rendered all jumbled when directly output in modern browsers, which is what you're seeing.

However, the selector hook parsers also has a regex-based parsing mode that can find non-HTML-constructs and is already utilized if you use {enclosing: false} in your SelectorHookParserConfig.

I will look into expanding that option to also work with self-closing tags when set to false.

MTobisch commented 5 days ago

Hey there!

I've just released v3.1.0 of the library which now supports self-closing tags (configured via the new allowSelfClosing option in each SelectorHookParserConfig). As its true by default, all you need to do is to enable regex-based selector parsing for your components.

An example could look like so:

  const parsers: HookParserEntry[] = [{
    component: TestComponent,
    parseWithRegex: true
  }];

  const content = `
    <h2>Hello from the the content string!</h2>
    <app-test [message]="'This is the first comp!'"/>
    <app-test [message]="'This is the second comp!'"/>
    <p>Text after component</p>
  `;
<ngx-dynamic-hooks [parsers]="parsers" [content]="content"></ngx-dynamic-hooks>