更换组件时停止角度重新加载iframe?

时间:2018-01-17 17:06:39

标签: angular

我有一个基于ngxadmin构建的角度应用程序。

https://github.com/akveo/ngx-admin

关于Angular 4.4.6。

应用在不同的信息中心之间切换。每个仪表板都有一个带有一些嵌入式图表的iframe。

问题在于,每次更改仪表板时,iframe都会重新加载。

与主角应用程序(完全缓存)相比,重新加载需要1-2秒,并且不会超快。

问题是,每次将iframe注入HTML时都会导致重新加载。已呈现的内容未被保留。

我已经阅读了很多地方,这是iframe的基本设计。如果将它们移回/插入DOM,则会重新加载它们。

我还试图通过使用HTTP缓存和CDN(Fastly)使它们尽可能快。这改善了情况,但我仍然面临着这些缓慢的加载时间。

我有没有办法阻止每次重新加载iframe?

有没有一种方法可以让角度不能删除HTML内容,而只是显示:没有它以便它仍然实际上是DOM的一部分?

我想到的另一个想法是隐藏iframe,然后复制body innerHTML并将其移动到我的角度应用程序中。然后只使用该内容。我不是非常关心安全性,因为我控制了两个应用程序,但我想在那时CSS会被打破。

一个想法是我可以将预先呈现的HTML写入iframe,而不是依赖于从'src'中获取它。每一次。

2 个答案:

答案 0 :(得分:1)

对不起,我的回复很晚,但是在将YouTube视频嵌入mi应用程序时遇到了同样的问题。我无法对嵌入式视频进行全屏显示,原因是调用了一些调整大小处理程序,从而触发了更改检测并重新加载了iframe。

无论如何,我设法使用@ angular / core的 ChangeDetectorRef 解决了此问题,该功能似乎在angular 2以后就可用。

我所做的是:

import { Component, ChangeDetectorRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html', // here goes your iframe
  styleUrls: ['./your-component.component.scss']
})
export class YourComponent implements AfterViewInit {

  constructor( private ref: ChangeDetectorRef ) { }

  ngAfterViewInit() {
    this.ref.detach()
  }
}

我知道这是一种解决方法,但并不是像您要分离整个应用程序那样,而是仅保留已加载的iframe。另外,在其余模板更新时,您还是会删除该小块。

希望这可以帮助您或其他遇到相同问题的人。

答案 1 :(得分:1)

我不知道我的问题和您的问题是否完全相同,但是在使用sanitizer.bypassSecurityResourceUrl作为iframe的src时遇到了问题:

<iframe [src]="sanitizer.bypassSecurityTrustStyle(url)"></iframe>

“ url”是字符串类型。这会在每个changeDetection中重置iframe。为了克服这个问题,可以使用自定义指令:

<iframe [cachedSrc]="url"></iframe>

这是指令的代码:

@Directive({
  selector: 'iframe'
})
export class CachedSrcDirective {

    @Input() 
    public get cachedSrc(): string {
        return this.elRef.nativeElement.src;
    }
    public set cachedSrc(src: string) {
        if (this.elRef.nativeElement.src !== src) {
            this.renderer.setAttribute(this.elRef.nativeElement, 'src', src);
        }
    }

    constructor(
        private elRef: ElementRef,
        private renderer : Renderer2
        ) { }
}

只要iframe位于DOM树中,并且src不变,我猜就可以了。也不需要使用DomSanitizer绕过URL:)