Необходимо вставить тег Script в angular 2

Я уже немного читал и искал, и почти все, что я нахожу, указывает на то, что тег script не может быть включен в шаблон в Angular 2.

мы специально удаляем теги из шаблонов, поскольку вы не должны использовать их для загрузки кода по требованию. https://github.com/angular/angular/issues/4903 [2015]

Однако - есть функция bypassSecurityTrustScript

Я хотел бы знать, когда и как bypassSecurityTrustScript в Angular 2 предполагается использовать?

Я знаю, что был задан аналогичный вопрос: Angular2 динамически вставить тег script, хотя никто не ответил на их вопрос о том, как использовать bypassSecurityTrustScript, и я не уверен, как предоставленный ответ на этот вопрос вопрос может даже работать, поскольку он, кажется, использует JavaScript в шаблоне.

Ответ 1

Наличие сценариев в ваших представлениях обычно является плохой практикой. Если вы настаиваете на этом, вы можете использовать этот компонент:

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();
    }
}

использование (inline):

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

использование (внешний):

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

Ответ 2

Оказывается, я думал об этом немного неправильно. Я пытался найти способ поместить скрипт в шаблон, используя стандартные переменные шаблона Angular. Когда Angular заполняет шаблон, он очищает значения и теги сценария теряются.

Мне удалось наконец получить теги сценария в следующей статье: https://netbasal.com/angular-2-security-the-domsanitizer-service-2202c83bd90#.7njysc6z1

После этого у меня возникла проблема, описанная следующим образом: Angular2 динамически вставляет тег сценария

Затем я переместил логику в класс компонентов на основе этого: Куда относятся манипуляции с DOM в Angular 2?

Ответ 3

У меня был аналогичный вариант использования, где я не знаю, будет ли HTML содержать тег script. Поскольку HTML5 не выполняет script, если он является частью назначения 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]);
    }
  }
}

Ответ 4

Согласно документации Angular, скрипт & lt; script & gt; Элемент запрещен и не может использоваться в шаблонах. & Lt; & сценарий GT; игнорируется при использовании в шаблонах.

Проверьте здесь. Угловая безопасность

Ответ 5

Включить jQuery в консоль JavaScript

Используйте следующее, чтобы решить вашу проблему. Он включает JQuery, вставляя теги скрипта в DOM, но он может работать для любой библиотеки тегов или JavaScript, которую вы пожелаете. При желании вы можете использовать атрибут innerHTML для настройки содержимого тега.