[转]angular2: including thirdparty js scripts in component
Script tags in component templates are removed. A workaround is to create the script tag dynamically in ngAfterViewInit()
See also https://github.com/angular/angular/issues/4903
import { DOCUMENT } from '@angular/common';
...
constructor(private @Inject(DOCUMENT) document,
private elementRef:ElementRef) {};
ngAfterViewInit() {
var s = this.document.createElement("script");
s.type = "text/javascript";
s.src = "http://somedomain.com/somescript";
this.elementRef.nativeElement.appendChild(s);
}
See also https://stackoverflow.com/a/9413803/217408
Adding script tags in Angular component template
Maybe a little late to the party here, but since the above answers do not work well with Angular SSR (e.g. document is not defined
server-side or document.createElement is not a function
), I decided to write a version that works for Angular 4+, in both server and browser context:
Component Implementation
import { Renderer2, OnInit, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
class MyComponent implements OnInit {
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _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);
}
}
Service Implementation
NOTE: Services cannot use Renderer2
directly. In fact, rendering element is supposed to be done by a Component. However, you might find yourself in situation where you want to automate the creation of JSON-LD script
tags on a page. A situation could be to invoke such function on route navigation change events. Hence I decided to add a version that works in a Service
context.
import { Renderer2, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/platform-browser';
class MyService {
constructor(@Inject(DOCUMENT) private _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);
}
}
The following works with Angular 5.2.7:
The required imports are:
import { Inject, AfterViewInit, ElementRef } from '@angular/core';
import { DOCUMENT } from '@angular/common';
Implement AfterViewInit:
export class HeroesComponent implements AfterViewInit {
If your component is implementing more that one interfaces, separate them by comma; for example:
export class HeroesComponent implements OnInit, AfterViewInit {
Pass the below arguments to constructor:
constructor(@Inject(DOCUMENT) private document, private elementRef: ElementRef) { }
Add ngAfterViewInit method of view life-cycle:
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);
}
Add afterScriptAdded member function.
This function will be called after the external script is loaded successfully. So the properties or functions you want to use from external js will be accessed in the body of this function.
afterScriptAdded() {
const params= {
width: '350px',
height: '420px',
};
if (typeof (window['functionFromExternalScript']) === 'function') {
window['functionFromExternalScript'](params);
}
}
Actually There is no Angular2 way of adding a script tag to a template. but you can do some trickfirst of all you will import AfterViewInit
and ElementRef
from angular2 like this :
import {Component,AfterViewInit,ElementRef} from 'Angular2/core';
then you will you will implement them in your class like that :
export class example1 implements AfterViewInit{}
and here is a very simple javascript dom trick you gonna do
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
}
}
I encountered the same issue, but additionally I had to load in a number of scripts, some of which could loaded in parallel, and others in series. This solution will work if you are using TypeScript 2.1 or greater, which has native support for async/await and transpiles to ES3/ES5:
async ngAfterViewInit() {
await this.loadScript("http://sub.domain.tld/first-script.js")
await this.loadScript("http://sub.domain.tld/second-script.js")
}
private loadScript(scriptUrl: string) {
return new Promise((resolve, reject) => {
const scriptElement = document.createElement('script')
scriptElement.src = scriptUrl
scriptElement.onload = resolve
document.body.appendChild(scriptElement)
})
}
For any scripts that can be loaded in parallel, you can take advantage of Promise.all:
async ngAfterViewInit() {
await Promise.all([
this.loadScript("http://sub.domain.tld/first-parallel.js"),
this.loadScript("http://sub.domain.tld/second-parallel.js")
])
await this.loadScript("http://sub.domain.tld/after-parallel.js")
}
Note: For promise rejection, you can try working with scriptElement.onerror = reject
in the loadScript()
function, however, I encountered some quirky behavior in this situation. If you want script to keep loading no matter what, you may want to experiment with resolving promises when onerror is called.
posted on 2019-02-12 14:18 freeliver54 阅读(222) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2015-02-12 [转]js add month 加n月
2007-02-12 珍惜(苏有朋)
2007-02-12 程序员的人生 该将如何规划?