我有一个后端数据库,其中包含html格式的帮助手册主题,包括具有单击功能的锚点。我的Angular(4.3.5)应用程序有一个主题树,当点击树主题时,主题的主体html从后端获得并显示在容器div中的主题树旁边。
我的问题是关于如何在容器div中显示html页面。 最初我尝试过:
<div [innerHtml]="htmlbody | safeHtmlPipe"></div>
此解决方案无法完全发挥作用,因为htmlbody包含其他页面的锚点:
<a (click)="loadNewPage(topicId)">display topic</a>
Angular正在点击处理程序清理(过滤掉)锚点。
我已关注此主题的许多Google链接,例如Dynamically displaying elements containing HTML with (click) functions Angular 2。 另外,我在Dynamic Injection in Angular 4中查看了一个包装器组件。但未能找到任何实际的工作代码示例,专门提供从动态源(从后端)加载html。 我想使用新的ngComponentOutlet指令并使其与AoT兼容。
有谁知道如何实现这一目标?
答案 0 :(得分:1)
由于没有人回答这个问题,所以这是一个有效的解决方案,尽管它不是理想的,它确实可以完美地运作。并且符合AOT标准。
模板:
<div id="pagecontainer" [innerHtml]="htmlbody | safeHtmlPipe"></div>
以下代码使用单击回调替换pagecontainer中的所有dom anchor href:
// use service to get backend html
this.db.get('getpage', pageId)
.subscribe(res => {
// load innerHtml with page markup
this.htmlPage = res.data;
// short pause (for template [innerHtml] = htmlbody)
setTimeout(() => {
// get all achors children of the page container
let pc = document.body.querySelector("#pagecontainer");
let x = pc.querySelectorAll('a');
Array.from(x).forEach(el => {
// get the href content
let hr = el.getAttribute('href');
if (hr != undefined) {
// replace href with onclick event
el.setAttribute('href', 'onclick=\"link()\"');
// bind click listener
el.addEventListener('click', e => {
// prevent browser precessing the anchor
e.preventDefault();
// callback with original href content
this.link(hr);
});
}
});
// scroll to the first h1
pc.getElementsByTagName('h1')[0].scrollIntoView();
this.g.showloading = false;
}, 100);
});
link(href) {
// call the topic on click handler with href to load the new page
}
为了完整起见,safeHtml管道:
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
// Ref: https://stackoverflow.com/questions/39794588/angular2-innerhtml-removes-styling
@Pipe({
name: 'safeHtmlPipe'
})
export class safeHtmlPipe implements PipeTransform {
constructor(private sanitizer:DomSanitizer){}
transform(html) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}