【问题标题】:Angular 4 Container Element with Dynamic Content - AOT friendly具有动态内容的 Angular 4 容器元素 - AOT 友好
【发布时间】:2017-08-21 02:31:09
【问题描述】:

我有一个后端数据库,其中包含 html 格式的帮助手册主题,包括具有点击功能的锚点。我的 Angular (4.3.5) 应用程序有一个主题树,当单击一个树主题时,主题的主体 html 从后端获取并显示在容器 div 中的主题树旁边。

我的问题是关于如何在容器 div 中显示 html 页面。 最初我尝试过:

<div [innerHtml]="htmlbody | safeHtmlPipe"></div>

此解决方案无法完全发挥作用,因为 htmlbody 包含指向其他页面的锚点:

<a (click)="loadNewPage(topicId)">display topic</a>

Angular 正在清理(过滤掉)点击处理程序上的锚点。

我关注了很多关于这个主题的谷歌链接,比如Dynamically displaying elements containing HTML with (click) functions Angular 2。 我还查看了Dynamic Injection in Angular 4 中的包装器组件。但未能找到任何具体提供从动态源(例如后端)加载 html 的工作代码的实际示例。 我想使用新的 ngComponentOutlet 指令并让它与 AoT 兼容。

有谁知道如何做到这一点?

【问题讨论】:

    标签: html angular


    【解决方案1】:

    由于没有人回答这个问题,这里有一个可行的解决方案,尽管它不是完美运行的理想方案。并且符合 AOT。

    模板:

    <div id="pagecontainer" [innerHtml]="htmlbody | safeHtmlPipe"></div>
    

    以下代码将页面容器内的所有 dom 锚点 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);
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-18
      • 2019-02-18
      • 2013-06-17
      • 2018-09-10
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 2018-12-25
      相关资源
      最近更新 更多