Issue
I have an HTML string that originates from the server. Since it's a legacy system, I'm unable to modify its format. However, I need to display this HTML content in the DOM. To achieve this, I'm utilizing the bypassSecurityTrustHtml
function provided by DomSanitizer
.
The issue lies within this HTML content, as it contains an anchor (<a>
) link that is intended to navigate to another page within the system. Currently, when I click on this link, it refreshes the entire page instead of performing internal routing.
In the provided example, you can see the HTML string that I'm rendering to the DOM. Additionally, there are two links with the routeLink
attribute that demonstrate internal routing (without page refresh). When you navigate to the /foo
route and click on the rendered link (which should navigate to /bar
), the entire page gets refreshed.
Is there a way to configure the rendering of this HTML content to enable internal routing instead of refreshing the entire page?
import { Component, inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideRouter, RouterLink, RouterOutlet } from '@angular/router';
import 'zone.js';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'foo',
standalone: true,
imports: [],
template: `
in foo!
<div [innerHtml]="html"></div>
`,
})
export class FooComponent {
private sanitizer = inject(DomSanitizer);
html = '';
ngOnInit() {
const htmlFromTheServer = `<h2>foo title</h2><a href="/bar">goto bar!</a>`;
this.html = this.sanitizer.bypassSecurityTrustHtml(
htmlFromTheServer
) as string;
}
}
@Component({
selector: 'bar',
standalone: true,
imports: [],
template: `in bar!`,
})
export class BarComponent {}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink],
template: `
<h1>Hello from {{ name }}!</h1>
<a routerLink="/foo">/foo</a> <br>
<a routerLink="/bar">/bar</a> <br>
<hr>
<router-outlet></router-outlet>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App, {
providers: [
provideRouter([
{ path: 'foo', component: FooComponent },
{ path: 'bar', component: BarComponent },
]),
],
});
Solution
In the component where you have <div [innerHtml]="html"></div>
, add a call to method that will handle the click on links: (click)='processLink($event)'
, so it'll be: <div [innerHtml]="html" (click)='processLink($event)'></div>
.
Then define the method as:
processLink(e) {
const element: HTMLElement = e.target;
if (element.nodeName === 'A') {
e.preventDefault();
const link = element.getAttribute('href');
this.router.navigate([link]);
}
}
So, basicly, you are taking the clicked html element from the DOM, finding the a
tag (or A
node), preventing the default behaviour of the click handler and instead take the href
value to treat it as router navigate link.
Of course, import the Router: import { Router } from '@angular/router'
and have it in constructor: public readonly router: Router
Answered By - Misha Mashina
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.