2017-02-25 43 views
3

脚本标签我已经做了一些阅读和搜索和几乎所有我找点到脚本标签不能被包含在角2需要插入的角度2

模板我们正在有意地从模板中删除标签,因为您不应该使用这些按需加载代码的 。 https://github.com/angular/angular/issues/4903 [2015年]

然而 - 有一个函数bypassSecurityTrustScript

我想知道何时以及如何在角2 bypassSecurityTrustScript打算使用?

我知道了类似的问题已经被问: Angular2 dynamically insert script tag - 尽管没有人回答了他们如何使用bypassSecurityTrustScript的问题,我不知道怎么样,因为它似乎使用JavaScript提供这个问题的答案可能连工作在模板内。

+0

的答案已经表示,它不是一个角度的问题,因此它也没有涉及到'DomSanitizer'。 –

+0

您试图解决的实际问题是什么?为什么你认为你需要在模板中包含脚本标签? – jonrsharpe

+0

那么何时,为什么以及如何使用bypassSecurityTrustScript? –

回答

5

原来我在想这有点不对。我试图找到一种方法,通过使用标准的Angular模板变量将脚本放入模板中。当Angular填充模板时,它将清理这些值,并因此脚本标记丢失。

我设法最终得到了脚本标记本文以下内容: https://netbasal.com/angular-2-security-the-domsanitizer-service-2202c83bd90#.7njysc6z1

这则给我留下了所描述的问题:Angular2 dynamically insert script tag

我然后转移逻辑到组件类在此基础上: Where does DOM manipulation belong in Angular 2?

+2

请提供[上下文链接](https:// stackoverflow。 COM /帮助/如何到结果)。外部托管信息可能会在没有警告的情况下消失 – James

5

在你的视图中有脚本通常是一种不好的做法。如果你坚持这样做,你可以使用这个组件:

scripthack.component.html:

<div #script style.display="none"> 
    <ng-content></ng-content> 
</div> 

scripthack.component.ts:

import { Component, ElementRef, ViewChild, Input } from '@angular/core'; 

@Component({ 
    selector: 'script-hack', 
    templateUrl: './scripthack.component.html' 
}) 
export class ScriptHackComponent { 

    @Input() 
    src: string; 

    @Input() 
    type: string; 

    @ViewChild('script') script: ElementRef; 

    convertToScript() { 
     var element = this.script.nativeElement; 
     var script = document.createElement("script"); 
     script.type = this.type ? this.type : "text/javascript"; 
     if (this.src) { 
      script.src = this.src; 
     } 
     if (element.innerHTML) { 
      script.innerHTML = element.innerHTML; 
     } 
     var parent = element.parentElement; 
     parent.parentElement.replaceChild(script, parent); 
    } 

    ngAfterViewInit() { 
     this.convertToScript(); 
    } 
} 

使用(在线):

<script-hack>alert('hoi');</script-hack> 

用法(外部):

<script-hack src="//platform.twitter.com/widgets.js" type="text/javascript"></script-hack> 
+0

这很有帮助。与此有关的一个问题是,在JS中,您经常使用“{”字符,这将在解析模板时引发错误。 ngNonBindable好像会是答案,但有一个[未解决的问题](https://github.com/angular/angular/issues/11859)ngNonBindable不处理非转义的“{”字符。 – dhockey

+1

谢谢你提到。我还没有遇到过(或不记得)。一种解决方案是使用一个单独的js文件。我用这个包含没有ts定义的javascript,但我认为这是一个不好的做法:D –

0

我有一个类似的用例,我不知道HTML是否包含脚本标记。由于HTML5并不执行脚本,如果它是innerHTML分配的一部分,我使用了一种稍微不同的方法。
这是插件系统的一部分,所以我需要能够按需添加html +脚本。这里

来源 - https://github.com/savantly-net/sprout-platform/blob/development/web/sprout-web-ui/src/app/dynamic/dynamic.component.ts

import { Component, Input, AfterViewInit, ViewChild, Directive, ElementRef } from '@angular/core'; 

@Directive({ 
    /* tslint:disable-next-line:directive-selector */ 
    selector: 'dynamic-directive' 
}) 
export class DynamicDirective {} 

@Component({ 
    template: `<dynamic-directive></dynamic-directive>` 
}) 
export class DynamicComponent implements AfterViewInit { 
    @Input() body: any; 
    @ViewChild(DynamicDirective, {read: ElementRef}) dynamic: ElementRef; 

    constructor() { } 

    // loads all the html from the plugin, but removes the script tags and appends them individually, 
    // since html will not execute them if they are part of the innerHTML 
    ngAfterViewInit(): void { 
    const div = document.createElement('div'); 
    div.innerHTML = this.body; 
    const scriptElements = []; 
    const scriptNodes = div.querySelectorAll('script'); 
    for (let i = 0; i < scriptNodes.length; i++) { 
     const scriptNode = scriptNodes[i]; 
     // Create a new script element so HTML5 will execute it upon adding to DOM 
     const scriptElement = document.createElement('script'); 
     // Copy all the attributes from the original script element 
     for (let aI = 0; aI < scriptNode.attributes.length; aI++) { 
     scriptElement.attributes.setNamedItem(<Attr>scriptNode.attributes[aI].cloneNode()); 
     } 
     // Add any content the original script element has 
     const scriptContent = document.createTextNode(scriptNode.textContent); 
     scriptElement.appendChild(scriptContent); 
     // Remove the original script element 
     scriptNode.remove(); 
     // add the new element to the list 
     scriptElements.push(scriptElement); 
    } 
    this.dynamic.nativeElement.appendChild(div); 
    // Finally add the new script elements to the DOM 
    for (let i = 0; i < scriptElements.length; i++) { 
     this.dynamic.nativeElement.appendChild(scriptElements[i]); 
    } 
    } 
}