Angular 6 - 在组件级别添加脚本并检查它是不是存在
Posted
技术标签:
【中文标题】Angular 6 - 在组件级别添加脚本并检查它是不是存在【英文标题】:Angular 6 - Adding script at component level and checking if it existsAngular 6 - 在组件级别添加脚本并检查它是否存在 【发布时间】:2019-03-20 14:45:45 【问题描述】:我有一个脚本,我只想在一个组件上运行。我已经设法在组件上添加脚本,但是发生了一些我不完全确定如何解决的事情。
-
如果我导航到组件,脚本会添加到 DOM,但不会触发。如果我刷新页面,它可以工作
如果我导航到另一个组件并返回,则会再次添加脚本,并且可以继续构建
component.ts
import Component, OnInit from '@angular/core';
import Renderer2, Inject from '@angular/core';
import DOCUMENT from '@angular/platform-browser';
@Component(
selector: 'app-privacy',
templateUrl: './privacy.component.html',
styles: []
)
export class PrivacyComponent implements OnInit
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document)
let s = this._renderer2.createElement('script');
s.type = `text/javascript`;
s.src = `../../assets/scripts/privacy.js`;
this._renderer2.appendChild(this._document.body, s);
ngOnInit()
【问题讨论】:
您应该为您的脚本元素添加一个 onload 回调,以便您知道它何时完成加载。至于删除脚本,我认为最好将其从组件的 ngOnDestroy 生命周期钩子中的 dom 中删除。 太好了,谢谢。关于第 2 点,您是否有示例说明如何在 ngDestroy 中删除添加的脚本? 您可以将 appendChild 返回的节点保存在组件中,并在 Destroy 生命周期钩子中简单地保存.remove()
。生病为你创建一个例子。
哦,我看到你在使用 Renderer2,我没有太多经验,但你可以在 Destroy hook 中尝试:this._renderer2.removeChild(this._document.body, s)
已排序,谢谢。如果你把它写成答案,我会标记它:)
【参考方案1】:
您需要将onload
(如果您需要支持IE,请确保也支持onreadystatechange
)处理程序添加到您的脚本元素中,该处理程序可以在脚本完成加载时调用您要执行的函数。
要删除 onNgDestroy 脚本,请在组件上保存 createElement?
的引用,并在 Destroy 生命周期挂钩中删除它。
import Component, OnInit, OnDestroy from '@angular/core';
import Renderer2, Inject from '@angular/core';
import DOCUMENT from '@angular/platform-browser';
@Component(
selector: 'app-privacy',
templateUrl: './privacy.component.html',
styles: []
)
export class PrivacyComponent implements OnInit, OnDestroy
private s: any;
constructor(private _renderer2: Renderer2, @Inject(DOCUMENT) private _document)
this.s = this._renderer2.createElement('script');
this.s.type = `text/javascript`;
this.s.src = `../../assets/scripts/privacy.js`;
this.s.onload = this.doneLoading;
this._renderer2.appendChild(this._document.body, this.s);
doneLoading ()
// do what you need to do
ngOnDestroy()
// this removes the script so it won't be added again when the component gets initialized again.
this._renderer2.removeChild(this._document.body, this.s)
ngOnInit()
【讨论】:
【参考方案2】:你运行这个js文件的方法是错误的,你应该做以下以干净的方式实现这一点:
-
将您的 js 文件添加到资产(例如 assets/js/privacy.js)
将文件添加到 .angular-cli.json 脚本中
现在,如果您在组件中声明它们,您可以从 Angular 组件中调用您的 js 函数
angular-cli.json
"scripts": [
"assets/js/privacy.js"
]
component.ts
import Component, OnInit from '@angular/core';
declare function myFunc(): any; // function from privacy.js
@Component(
selector: 'app-privacy',
templateUrl: './privacy.component.html',
styles: []
)
export class PrivacyComponent implements OnInit
constructor()
ngOnInit()
myFunc(); // call it
【讨论】:
这只有在全局加载脚本时才有效(即添加到 angular.json 中的脚本数组中) @thinkwinwin 他已在全球范围内添加,请参阅 s.src =../../assets/scripts/privacy.js
; true 添加文件到 .angular-cli.json 丢失
我还没有全局添加。那就是它存储在我的目录中的位置。如果有帮助的话。
为什么你不能全局添加这个而不是做这样的黑客攻击? :)以上是关于Angular 6 - 在组件级别添加脚本并检查它是不是存在的主要内容,如果未能解决你的问题,请参考以下文章
Angular 6 - ng-bootstrap - 在选项卡级别添加自定义数据属性