在 HTML 字符串中传递 angular routerLink URL 的最佳方式
Best way to pass angular routerLink URL's in an HTML string
我的 angular 应用程序中有一个通知服务,通常你这样称呼它
this.notificationsService.showError('My Title', 'My Message...');
我也希望能够在消息中传递应用程序 link,我知道我需要允许 SafeHtml
输入,如下所示:
this.notificationsService.showError(
'Error!',
this.domSanitizer.bypassSecurityTrustHtml(
`Something has gone wrong, but you can go to <a routerLink="'/home/accounts-list'">home page</a> to start over.`
)
);
在我的服务中,这就是我用它做的:
showError(title: string, message: string | SafeHtml): void {
const newNotification: INotification = {
title,
message,
htmlMessage: typeof message !== 'string'
};
this.notifications.push(newNotification);
}
然后我这样展示:
<div class="toast" *ngFor="let n of notificationsService.notificationsList">
<div class="toast-header">
<strong>{{n.title}}</strong>
</div>
<div class="toast-body" *ngIf="!n.htmlMessage">{{n.message}}</div>
<div class="toast-body" *ngIf="n.htmlMessage" [innerHTML]="n.message"></div>
</div>
那么……进入正题!这只是在某种程度上起作用,因为 HTML 得到了,但显然它没有被 angular 解析以使 routerLink
起作用。实际 HTML 输出到浏览器是:
<a routerlink="'/home/accounts-list'">home page</a>
然而,它不可点击,因为 link 实际上被 angular 解析会输出这个 HTML:
<a routerlink="'/home/accounts-list'" ng-reflect-router-link="/home/accounts-list" href="/home/accounts-list">home page</a>
如何让这些 link 工作?
我的处理方式是否正确?
由于HTML不是angular编译器编译的,所以没有好的解决办法。 :)
有一些 hacks 可以实现你想要的。但它们很脏,可能不安全。
一个解决方案是创建一个位于宿主元素上的指令。如果点击的元素具有 routerlink 属性,它会监视主机上的点击并阻止默认操作。然后它只调用带有 routerlink 属性值的 router.navigate 函数。
我准备了一个关于 stackblitz 的简单示例:https://stackblitz.com/edit/angular-ttfwwg
这是我根据@cgTag 的评论和建议最终做的
在我的页面上显示错误我有这个:
<ng-template #errorMessageTemplate>
Something has gone wrong, but you can go to the <a [routerLink]="['/home/accounts-list']">home page</a>
</ng-template>
@ViewChild('errorMessageTemplate') errorMessageTemplate!: TemplateRef<NgTemplateOutlet>;
someMethod(): void {
this.notificationsService.showError('Error!', this.errorMessageTemplate);
}
在我的服务中,我有这个:
showError(title: string, message: string | TemplateRef<NgTemplateOutlet>): void {
const newNotification: INotification = {
title,
message,
messageAsTemplate: typeof message !== 'string'
};
this.notifications.push(newNotification);
}
然后我这样展示:
<div class="toast" *ngFor="let n of notificationsService.notificationsList">
<div class="toast-header">
<strong>{{n.title}}</strong>
</div>
<div class="toast-body" *ngIf="!n.messageAsTemplate">{{n.message}}</div>
<div class="toast-body" *ngIf="n.messageAsTemplate">
<ng-container [ngTemplateOutlet]="n.message"></ng-container>
</div>
</div>
我的 angular 应用程序中有一个通知服务,通常你这样称呼它
this.notificationsService.showError('My Title', 'My Message...');
我也希望能够在消息中传递应用程序 link,我知道我需要允许 SafeHtml
输入,如下所示:
this.notificationsService.showError(
'Error!',
this.domSanitizer.bypassSecurityTrustHtml(
`Something has gone wrong, but you can go to <a routerLink="'/home/accounts-list'">home page</a> to start over.`
)
);
在我的服务中,这就是我用它做的:
showError(title: string, message: string | SafeHtml): void {
const newNotification: INotification = {
title,
message,
htmlMessage: typeof message !== 'string'
};
this.notifications.push(newNotification);
}
然后我这样展示:
<div class="toast" *ngFor="let n of notificationsService.notificationsList">
<div class="toast-header">
<strong>{{n.title}}</strong>
</div>
<div class="toast-body" *ngIf="!n.htmlMessage">{{n.message}}</div>
<div class="toast-body" *ngIf="n.htmlMessage" [innerHTML]="n.message"></div>
</div>
那么……进入正题!这只是在某种程度上起作用,因为 HTML 得到了,但显然它没有被 angular 解析以使 routerLink
起作用。实际 HTML 输出到浏览器是:
<a routerlink="'/home/accounts-list'">home page</a>
然而,它不可点击,因为 link 实际上被 angular 解析会输出这个 HTML:
<a routerlink="'/home/accounts-list'" ng-reflect-router-link="/home/accounts-list" href="/home/accounts-list">home page</a>
如何让这些 link 工作?
我的处理方式是否正确?
由于HTML不是angular编译器编译的,所以没有好的解决办法。 :)
有一些 hacks 可以实现你想要的。但它们很脏,可能不安全。
一个解决方案是创建一个位于宿主元素上的指令。如果点击的元素具有 routerlink 属性,它会监视主机上的点击并阻止默认操作。然后它只调用带有 routerlink 属性值的 router.navigate 函数。
我准备了一个关于 stackblitz 的简单示例:https://stackblitz.com/edit/angular-ttfwwg
这是我根据@cgTag 的评论和建议最终做的
在我的页面上显示错误我有这个:
<ng-template #errorMessageTemplate>
Something has gone wrong, but you can go to the <a [routerLink]="['/home/accounts-list']">home page</a>
</ng-template>
@ViewChild('errorMessageTemplate') errorMessageTemplate!: TemplateRef<NgTemplateOutlet>;
someMethod(): void {
this.notificationsService.showError('Error!', this.errorMessageTemplate);
}
在我的服务中,我有这个:
showError(title: string, message: string | TemplateRef<NgTemplateOutlet>): void {
const newNotification: INotification = {
title,
message,
messageAsTemplate: typeof message !== 'string'
};
this.notifications.push(newNotification);
}
然后我这样展示:
<div class="toast" *ngFor="let n of notificationsService.notificationsList">
<div class="toast-header">
<strong>{{n.title}}</strong>
</div>
<div class="toast-body" *ngIf="!n.messageAsTemplate">{{n.message}}</div>
<div class="toast-body" *ngIf="n.messageAsTemplate">
<ng-container [ngTemplateOutlet]="n.message"></ng-container>
</div>
</div>