我已经完成了一些阅读和搜索,而且几乎我发现的一切都指出脚本标签不能包含在Angular 2的模板中。
我们会像您一样故意从模板中删除标签 不应该使用它们按需加载代码。 https://github.com/angular/angular/issues/4903 [2015]
然而 - 有一个函数bypassSecurityTrustScript
我想知道Angular 2中的bypassSecurityTrustScript
何时以及如何使用?
我知道有类似的问题被问到:
Angular2 dynamically insert script tag - 虽然没有人回答他们如何使用bypassSecurityTrustScript
的问题,但我不确定提供的问题答案是如何工作的,因为它似乎在模板中使用JavaScript。
答案 0 :(得分:19)
在您的视图中使用脚本通常是一种不好的做法。如果你坚持这样做,你可以使用这个组件:
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>
答案 1 :(得分:7)
原来我觉得这有点不对劲。我试图通过使用标准的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 :(得分:0)
我有一个类似的用例,我不知道HTML是否包含脚本标记。由于HTML5不是执行脚本(如果它是innerHTML分配的一部分),我使用的方法略有不同。
这是插件系统的一部分,所以我需要能够按需添加html +脚本。
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]);
}
}
}
答案 3 :(得分:0)
根据Angular文档,