script importar dynamically component javascript angular json-ld angular2-universal

javascript - importar - load external js script dynamically in angular 4



Agregar etiquetas de script en la plantilla de componente angular (5)

Lo siguiente funciona con Angular 5.2.7:

Las importaciones requeridas son:

import { Inject, AfterViewInit, ElementRef } from ''@angular/core''; import { DOCUMENT } from ''@angular/common'';

Implemente AfterViewInit:

export class HeroesComponent implements AfterViewInit {

Si su componente está implementando más de una interfaz, sepárelas por comas; por ejemplo:

export class HeroesComponent implements OnInit, AfterViewInit {

Pase los argumentos a continuación al constructor:

constructor(@Inject(DOCUMENT) private document, private elementRef: ElementRef) { }

Agregue el método ngAfterViewInit para ver el ciclo de vida:

ngAfterViewInit() { const s = this.document.createElement(''script''); s.type = ''text/javascript''; s.src = ''//external.script.com/script.js''; const __this = this; //to store the current instance to call //afterScriptAdded function on onload event of //script. s.onload = function () { __this.afterScriptAdded(); }; this.elementRef.nativeElement.appendChild(s); }

Agregar función de miembro afterScriptAdded.

Se llamará a esta función después de que el script externo se cargue correctamente. Por lo tanto, se accederá a las propiedades o funciones que desea utilizar desde js externos en el cuerpo de esta función.

afterScriptAdded() { const params= { width: ''350px'', height: ''420px'', }; if (typeof (window[''functionFromExternalScript'']) === ''function'') { window[''functionFromExternalScript''](params); } }

Angular2 elimina las etiquetas <script> automáticamente de las plantillas para evitar que las personas utilicen esta funcionalidad como cargador de "hombre pobre" .

El problema aquí es que las etiquetas de script actualmente tienen más usos que simplemente cargar código u otros archivos de script. Existe la posibilidad de que en el futuro se introduzcan más funcionalidades alrededor de las etiquetas <script> .

Un uso actual es JSON-LD que toma el formato

<script type="application/ld+json"> { "@context":"http://schema.org", "@type":"HealthClub", ... } </script>

Una ngAfterViewInit comúnmente sugerida es agregar dinámicamente etiquetas de script al documento a través del ngAfterViewInit , pero esto obviamente no es una práctica ng2 adecuada y no funcionará en el lado del servidor, lo que obviamente JSON-LD obviamente debe poder hacer.

¿Hay alguna otra solución que podamos usar para incluir etiquetas <script> en las plantillas de angular2 (incluso si la etiqueta es inerte dentro del navegador) o es este un caso en el que el marco es demasiado obstinado? ¿Qué otras soluciones podrían existir si esta situación no se puede resolver en angular2?


No hay forma de Angular2 de agregar una etiqueta de script a una plantilla.

El uso de require(...) para cargar scripts externos desde la clase de componentes se mencionó como una solución alternativa (no lo he probado yo mismo)

Para agregar dinámicamente una etiqueta de script use

constructor(private elementRef:ElementRef) {}; ngAfterViewInit() { var s = document.createElement("script"); s.type = "text/javascript"; s.src = "http://somedomain.com/somescript"; this.elementRef.nativeElement.appendChild(s); }

Consulte también angular2: incluye scripts de terceros js en el componente


Tal vez un poco tarde para la fiesta aquí, pero dado que las respuestas anteriores no funcionan bien con SSR angular (por ejemplo, el document is not defined en el lado del servidor o document.createElement is not a function ), decidí escribir una versión que funcione para Angular 4+, tanto en el contexto del servidor como del navegador :

Implementación de componentes

import { Renderer2, OnInit, Inject } from ''@angular/core''; import { DOCUMENT } from ''@angular/common''; class MyComponent implements OnInit { constructor( private _renderer2: Renderer2, @Inject(DOCUMENT) private _document: Document ) { } public ngOnInit() { let s = this._renderer2.createElement(''script''); s.type = `application/ld+json`; s.text = ` { "@context": "https://schema.org" /* your schema.org microdata goes here */ } `; this._renderer2.appendChild(this._document.body, s); } }

Implementación de servicio

NOTA: Los servicios no pueden usar Renderer2 directamente. De hecho, se supone que la representación de un elemento la realiza un Componente . Sin embargo, es posible que se encuentre en una situación en la que desee automatizar la creación de etiquetas de script JSON-LD en una página. Como ejemplo, una situación podría ser invocar dicha función en eventos de cambio de navegación de ruta. Por lo tanto, decidí agregar una versión que funcione en un contexto de Service .

import { Renderer2, Inject } from ''@angular/core''; import { DOCUMENT } from ''@angular/common''; /** * Use a Service to automate creation of JSON-LD Microdata. */ class MyService { constructor( @Inject(DOCUMENT) private _document: Document ) { } /** * Set JSON-LD Microdata on the Document Body. * * @param renderer2 The Angular Renderer * @param data The data for the JSON-LD script * @returns Void */ public setJsonLd(renderer2: Renderer2, data: any): void { let s = renderer2.createElement(''script''); s.type = ''application/ld+json''; s.text = `${JSON.stringify(data)}`; renderer2.appendChild(this._document.body, s); } }


En realidad, no hay una forma Angular2 de agregar una etiqueta de script a una plantilla. pero puedes hacer algún truco antes que nada , importarás AfterViewInit y ElementRef desde angular2 de esta manera:

import {Component,AfterViewInit,ElementRef} from ''Angular2/core'';

entonces lo implementarás en tu clase así:

export class example1 implements AfterViewInit{}

y aquí hay un truco dom de javascript muy simple que vas a hacer

export class example1 implements AfterViewInit{ ngAfterViewInit() { var s=document.createElement("script"); s.type="text/javascript"; s.innerHTML="console.log(''done'');"; //inline script s.src="path/test.js"; //external script } }


const head = document.getElementsByTagName(''head'')[0]; const _js = document.createElement(''script''); _js.type = ''text/javascript''; _js.appendChild(document.createTextNode(''{your js code here}'')); head.appendChild(_js);

esto se puede colocar en cualquier lugar que desee y es un buen enfoque