【问题标题】:Import 3rd party javascript libraries in Angular single components在 Angular 单个组件中导入 3rd 方 javascript 库
【发布时间】:2018-06-18 18:53:49
【问题描述】:

我目前正在开发一个 Angular4 应用程序,我想导入一些 javascript 库,但仅用于单个组件。 目前我可以通过在.angular-cli.json 中定义它们的路径来轻松导入这些库:

{
   "scripts": [
      "../node_modules/jquery/dist/jquery.min.js",
      "../node_modules/jqueryui/jquery-ui.js",
      "../src/assets/js/jquery/cometd/org-cometd.js",
      "../src/assets/js/jquery/cometd/jquery.cometd.js",
   ],
   ...
}

但是,将为所有应用程序导入上述脚本。有没有办法只为特定组件导入它们? 我尝试将它们导入到组件中,如下所示,但没有成功。

import { Component, OnInit, ViewEncapsulation, Inject } from '@angular/core';
...
import "../../../../../node_modules/jquery/dist/jquery.min.js";
import "../../../../../node_modules/jqueryui/jquery-ui.js";
import "../../../../assets/js/jquery/cometd/org-cometd.js";
import "../../../../assets/js/jquery/cometd/jquery.cometd.js";

@Component({
   selector: '...',
   templateUrl: '...',
   styleUrls: '...',
   encapsulation: ViewEncapsulation.None
})

export class MyComponent implements OnInit {
   ...
}

[UPDATE] - 我忘了提到我目前正在使用 ViewEncapsulation.None 来将一些 css 文件中的样式应用到组件中。不确定这个细节是否与问题有关。

【问题讨论】:

  • 您可以使用资产文件夹中的路径或cdn document.head.appendChild(...path);将它们添加到document
  • 谢谢,它似乎至少适用于某些库...

标签: angular typescript angular-components angular2-components


【解决方案1】:

您可以使用import 将它们导入到组件中。例如对于jQuery,它将是

import * as $ from 'jquery';

这意味着“从 'jquery' 库中将所有内容导入为 '$'(并将其进一步用作 '$')”,并且您实际上不需要将另一个导入包含到 .angular.cli.json。它适用于 Angular 5(我现在已经对其进行了测试),我认为它也应该适用于 2 和 4 版本。为确保其正常工作,您可以在ngOnInit 块中写入console.log($)(例如)。

【讨论】:

  • 使用这个我仍然得到控制台错误scripts.bundle.js:3186 Uncaught ReferenceError: jQuery is not defined。我已经通过npm install --save jquery 安装了 jquery 并删除了对 angular-cli.json 中脚本的引用
  • 这有点奇怪,因为我已经生成了新的 Angular 5 项目并导入了 jQuery,并且无需额外配置就可以正常工作 =/
  • 我忘了提到我目前正在使用 ViewEncapsulation.None。我不确定这个细节是否相关......
  • @DavidR,我认为应该不会影响。
  • @DavidR 尝试在“Uncaught ReferenceError: jQuery is not defined”中使用小写字母
【解决方案2】:

您只需获取 src js 并将其导入您的组件即可。

这是我做的传单应用程序的一个例子:

package.json:

"leaflet.markercluster": "^1.1.0",
"leaflet-draw": "^0.4.12",

random1.component.ts : 带有markercluster 库示例

declare const L: any;
import 'leaflet.markercluster';

export function initMarkerCluster(map: L.Map, mapService: LeafletService) {
  // Set the ClusterMarkerLayer
  const cluster = L.markerClusterGroup();
  ...
}

random2.component.ts : 带有leaflet.draw 库示例

declare const L: any;
import 'leaflet-draw/dist/leaflet.draw-src';

export function drawPlugin(map: L.Map, mapService: LeafletService) {
  const drawnItems: L.FeatureGroup = L.featureGroup().addTo(map);
  const drawControl = initDrawControl(drawnItems);
  map.addControl(drawControl);
  ...
}

注意:在这些传单库中,有传单的命名空间 L,所以我声明了一个全局变量,但你不应该需要它。

【讨论】:

  • 感谢您的回答 ;) 如果我要导入的 js 文件是自定义文件而不是来自第 3 方怎么办?
  • 没关系,应该可以正常工作。在这里,我的导入是针对来自node_modules 的传单库,因此您只需要更改导入路径。一旦它被导入到组件中,它就会在运行时使用。如果文件不存在,它会告诉您导入不正确。您可以尝试从您的自定义文件中调用一个方法,它应该工作相同。检查这些文件是如何制作的,以确保它以相同的方式工作。
  • 我有很多自定义的js文件要导入,我真的需要为每个文件声明一个const吗?这些文件大多声明了全局变量和函数...
  • 不,正如我在最后的说明中所说,这是我的传单库中的特定内容,该库将所有内容都封装在命名空间 L 中。如果您的 JS 文件中只有函数或其他内容,只需导入它们就足够了。
【解决方案3】:

像 jQuery 和 bootstrap 这样的东西是全局的,并且可以被应用程序使用。但是,最好让它们可注入,从而可以从单个组件中引用。

首先安装jQuery

npm install --save jquery
npm install -D @types/jquery

第二次做一个注入模块

import { NgModule } from '@angular/core';
import { InjectionToken } from '@angular/core';
import * as jquery from 'jquery';

export const JQUERY = new InjectionToken<jquery>('jQuery');

export function _jquery(): jquery {
  return jquery;
}

@NgModule({
  providers: [{
    provide: JQUERY,
    useFactory: _jquery
  }]
})
export class JqueryTokenModule { }

第三,在你的模块中:

providers: [{provide: JQUERY, useValue: _jquery}]

最后,将它注入到你的组件中

constructor(@Inject(JQUERY) private $) {
  // use `this.$` which is jQuery
}

【讨论】:

    猜你喜欢
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2018-02-03
    相关资源
    最近更新 更多