[转]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.
[转]angular2: including thirdparty js scripts in component的更多相关文章
- 使用纯粹的JS构建 Web Component
原文链接:https://ayushgp.github.io/htm...译者:阿里云 - 也树 Web Component 出现有一阵子了. Google 费了很大力气去推动它更广泛的应用,但是除 ...
- vue.js组件(component)
简介: 组件(Component)是 Vue.js 最强大的功能之一. 组件可以扩展 HTML 元素,封装可重用的代码. 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面 ...
- [转] angular2+highcharts+chart.js
这里是在ionic2下使用highchairs和chart.js的简单示例chartjs部分参考http://www.jianshu.com/p/bc18132da812 1.安装hightchart ...
- React.js Tutorial: React Component Lifecycle
Introduction about React component lifecycle. 1 Lifecycle A React component in browser can be any of ...
- loadrunner12.5-vugen回放脚本提示:URL=“http://www.testclass.net/js/scripts.js”的常规连接当前无套接字 (16 不足) 可用,是什么意思呢?怎么理解呢?
会发生这个报错,是因为每个浏览器都有一个限制,检查哪个浏览器客户正在模拟, 通常只允许16个并发连接. 如果超过此超过接数,将显示该消息,通知您没有可用的连接. 而max connection的默认值 ...
- [Node.js] Configuring npm package.json scripts
With a node package manager's (npm) package.json script property, you can preconfigure common tasks ...
- salesforce lightning零基础学习(八) Aura Js 浅谈一: Component篇
我们在开发lightning的时候,常常会在controller.js中写 component.get('v.label'), component.set('v.label','xxValue'); ...
- 如何在ASP.NET 5上搭建基于TypeScript的Angular2项目
一.前言 就在上月,公司的一个同事建议当前的前端全面改用AngularJs进行开发,而我们采用的就是ASP.NET 5项目,原本我的计划是采用TypeScript直接进行Angular2开发.所以借用 ...
- Karma 5:集成 Karma 和 Angular2
集成 Karma 和 Angular2 我们需要做很多工作,由于需要使用 TypeScript 进行开发,首先需要正确配置 Typescript ,然后正确配置对 Angular2 的引用.还要创建 ...
随机推荐
- Python Memo 赋值与ID (Assignment & id())
利用Python内置函数id()找出内部地址,探讨赋值与内建地址. id()的官方解释:this is the address of the object in memory 那么 a =1 是什么意 ...
- Redis-07.Spring Data整合Jedis
Spring整合Jedis 1.单实例(想节约时间的请直接拖到下面跳过1.2部分) step1:毫无疑问,首先需要在pom.xml中配置Jedis依赖 <dependency> <g ...
- 网易云通过KCSP认证,云原生技术实力再获认可
近日,网易云通过KCSP认证,正式成为CNCF官方认可的Kubernetes服务提供商,也标志着网易云在云原生领域的技术实力得到了业界认可. Kubernetes是第一个从CNCF毕业的开源项目,凭借 ...
- 工具安装(mac)
1. iterm 2. nvm 3. node 4. git 5. VScode 6. postman 1.安装iterm2安装路径 https://www.iterm2.com/使用技巧https: ...
- Akka-CQRS(0)- 基于akka-cluster的读写分离框架,构建gRPC移动应用后端架构
上一篇我们讨论了akka-cluster的分片(sharding)技术.在提供的例子中感觉到akka这样的分布式系统工具特别适合支持大量的带有内置状态的,相对独立完整的程序在集群节点上分布运算.这里重 ...
- 微信小程序中如何使用WebSocket实现长连接(含完整源码)
本文由腾讯云技术团队原创,感谢作者的分享. 1.前言 微信小程序提供了一套在微信上运行小程序的解决方案,有比较完整的框架.组件以及 API,在这个平台上面的想象空间很大.腾讯云研究了一番之后,发现 ...
- 每天学点SpringCloud(八):使用Apollo做配置中心
由于Apollo支持的图形化界面相对于我们更加的友好,所以此次我们使用Apollo来做配置中心 本篇文章实现了使用Apollo配置了dev和fat两个环境下的属性配置.Apollo官方文档https: ...
- JavaScript标识符与关键字和保留字
区分大小写 JavaScript中的一切(变量.函数名.操作符)都区分大小写.例如,变量名itbsl和变量名ITbsl是两个不同的变量. 标识符 所谓标识符,就是指变量.函数.属性的名字,或者函数的参 ...
- SpringBoot 项目打包后运行报 org.apache.ibatis.binding.BindingException
今天把本地的一个SpringBoot项目打包扔到Linux服务器上,启动执行,接口一访问就报错,但是在本地Eclipse中启动执行不报错,错误如下: org.apache.ibatis.binding ...
- Android精通之Handler讲解
版权声明:未经博主允许不得转载 一:简介 [达叔有道]软件技术人员,时代作者,从 Android 到全栈之路,我相信你也可以!阅读他的文章,会上瘾!You and me, we are family ...