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 - 如何在组件级别实现异常处理

Angular 6 - ng-bootstrap - 在选项卡级别添加自定义数据属性

带有静态页面或组件的 Angular? (组件太多?)

自定义组件未在 Ionic v4 + Angular 6 中显示

当页面在 Angular 10 中完全加载时调用组件函数

在Component中加载多个脚本