简体   繁体   中英

Need to modify dynamic content after rendering without breaking bindings

I have a service which is called after events which trigger page content changes. This service currently inspects all the viewable HTML on the rendered page for key words and then creates links to a glossary where those key words are used. The page content comes from many sources, including various components and external textual data. Initially this was done by finding all the elements and then searching and modifying the nativeElement.innerHTML which works fine on events that trigger a complete page refresh; in components where the text is based on template bindings, those bindings won't update after the innerHTML changes. I know modifying the innerHTML is bad...

I've tried using the root ViewContainerRef, and ViewRef as starting points but don't see way to access all the page content including content in multi-level child components. Additionally some of the content is added via router-outlet. I was hoping to either dynamically modify the templates, or the rendered content while allowing the component to still render the content when data changes and my service to post process again. Some components are from imported libraries, or receive their data directly, so modifying the component source code doesn't seem like the best option.

Using a MutationObserver you can subscribe to changes of text in the document, then you can manipulate the DOM in a way that doesn't break Angular, ie don't change the innerHTML of a node, but rather, insert a sibling with the new HTML and hide (don't remove) the original node.

I've written a stackblitz that demonstrates this.

https://stackblitz.com/edit/angular-highlighter2

EDIT I created an Angular library with all the code, see https://www.npmjs.com/package/ngx-html-highlighter

I found that by temporarily disabling, forcing change detection, then enabling the component on a data change, it would cause the component to be removed and recreated with working bindings. This is not an optimal solution, but did work as an initial fix. I'll attempt to try the above solution.

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