[转]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 的引用.还要创建 ...
随机推荐
- Java 8 特性
1.简介 毫无疑问,Java 8是自Java 5(2004年)发布以来Java语言最大的一次版本升级,Java 8带来了很多的新特性,比如编译器.类库.开发工具和JVM(Java虚拟机).在这篇教程 ...
- Teradata Delete Database and Drop Database
DELETE DATABASE and DELETE USER statements delete all data tables, views, and macros from a database ...
- AngularJS 关于ng-model和ng-bind还有{{}}
What's the difference between ng-model and ng-bind ng-bind has one-way data binding ($scope --> v ...
- IDEA的Database管理台如何显示
1.找出database的显示view 2.点击设置数据库,下载驱动文件,直接点击下载就行了,用什么数据库就下什么 3.填写服务器地址和用户名密码,点击测试,成功就表示连上了 4.一些常用按钮 5.目 ...
- Exp5MSF基础应用——20164325王晓蕊
1.实验要求 一个主动攻击实践,ms08_067; 一个针对浏览器的攻击,MS11-003(唯一): 一个针对客户端的攻击,adobe_toolbutton: 成功应用任何一个辅助模块Ipidseq( ...
- iOS TouchID & FaceID
import UIKit import LocalAuthentication //指纹识别必须用真机测试,并且在iOS8以上系统,如果是FaceID至少IOS11以上. class Authenti ...
- Linux 区别 chown和chmod的用法
chown用法用来更改某个目录或文件的用户名和用户组的chown 用户名:组名 文件路径(可以是就对路径也可以是相对路径)例1:chown root:root /tmp/tmp1就是把tmp下的tmp ...
- 亲子编程玩Micro:bit-动力小车“麦昆”
少儿编程之风已经吹进各大城市,编程猫.乐博机器人.童程童美等专业培训机构逐渐进入大家的视野,年龄段已经从K12逐渐降低到幼儿园中班.其实,少儿编程的门槛并不高,它不会让孩子一上手就去接触代码,而是会通 ...
- Android开发 - 掌握ConstraintLayout(九)分组(Group)
使用ConstraintLayout后我们的布局是没有层级关系的,各个View之间都是平级关系,但是如果根据某个业务条件来控制多个View的显示与否,我们需要分别对每个View进行控制,需要调用多次s ...
- 使用githubpages主题NexT的语法
使用githubpages主题NexT的语法 NexT 前言 不知道为啥?网站总是不出现? 添加「标签」页面 title: 标签测试文章 tags: - Testing - Another Tag - ...