2017-02-25 101 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]); 
    } 
    } 
}