66 votes

Angular 2 : importer un fichier js externe dans un composant

Je vais importer ceci d3gauge.js dans un de mes composants angular2, memmon.component.ts fichier.

import '../../../../js/d3gauge.js';
export class MemMonComponent {
    createMemGauge() {
        new drawGauge(this.opt);  //drawGauge() is a function inside d3gauge.js
    }
}

et dans le fichier modèle correspondant, ajoutez

<script src="../../../../js/d3gauge.js"></script>

Mais ça ne marche pas, drawGauge est introuvable.

Donc,

  1. quelles sont les étapes correctes pour importer un fichier js externe dans angular2 ?
  2. puisque j'utilise webpack, est-il possible de le faire dans webpack ? Je me réfère à ceci question la solution webpack proposée ne fonctionne pas pour moi car .ensure ne peut pas être résolu.

2 votes

Vous devez créer ou importer des typages (*.d.ts) pour le fichier.

81voto

Ankit Singh Points 15545

Idéalement, vous devez avoir .d.ts fichier de typage pour laisser Linting travail.

Mais il semble que d3gauge n'en a pas, vous pouvez demander aux développeurs de vous en fournir et espérer qu'ils vous écouteront.


Alternativement, vous pouvez résoudre ce problème spécifique en faisant ceci

declare var drawGauge: any;

import '../../../../js/d3gauge.js';
export class MemMonComponent {
    createMemGauge() {
        new drawGauge(this.opt);  //drawGauge() is a function inside d3gauge.js
    }
}

Si vous l'utilisez dans plusieurs fichiers, vous pouvez créer un fichier d3gauage.d.ts avec le contenu ci-dessous

declare var drawGauge: any;

et le référencer dans votre boot.ts (bootstrap) en haut, comme ceci

///<reference path="../path/to/d3gauage.d.ts"/>

1 votes

Merci. Une dernière question, quand est-ce que le declare var drawGauge: any; être référencé, au moment de transpiler ce fichier ts ? Ou, dit d'une autre manière, lorsque new drawGauge(this.opt) comment le compilateur sait-il que le drawGauge() est en fait dans d3gauge.js ?

0 votes

Oui, sur transpile, il doit savoir qu'il y a ou qu'il y aura quelque chose de nommé. d3gauge . Dans la deuxième question, ce n'est pas le cas, d3gauge.js l'affecte à un global dans le dom et c'est à partir de là qu'il est appelé à l'exécution.

0 votes

J'ai ReferenceError: drawGauge is not defined . Est-ce parce que j'utilise webpack ?

56voto

Après avoir perdu beaucoup de temps à trouver sa solution, J'en ai trouvé un . Pour vous faciliter la tâche, j'ai utilisé le code complet avec lequel vous pouvez remplacer votre fichier entier.

Il s'agit d'une réponse générale. Disons que vous voulez importer un fichier nommé testjs.js dans votre composant angular 2. Créez testjs.js dans votre dossier assets :

actifs > testjs.js

function test(){
    alert('TestingFunction')
}

inclure testjs.js dans votre index.html

index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Project1</title>
  <base href="http://stackoverflow.com/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <script src="./assets/testjs.js"></script>

</head>
<body>
  <app-root>Loading...</app-root>
</body>
</html>

Dans votre app.component.ts ou dans n'importe quel fichier component.ts où vous voulez appeler ce js, déclarez une variable et appelez la fonction comme ci-dessous :

app.component.ts

import { Component } from '@angular/core';

declare var test: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {
  title = 'app works!';

  f(){
    new test();
  }
}

Enfin dans votre app.component.html tester la fonction

app.component.html

<h1>
  <button (click)='f()'>Test</button>
</h1>

1 votes

Devons-nous déclarer le nom de la fonction sur le composant, et si j'ai plusieurs fonctions, dois-je toutes les déclarer ? De plus, cela ne fonctionne pas, je reçois ces erreurs "ERROR ReferenceError : test is not defined" et "Refused to execute script from ' localhost:4200/assets/custom.js parce que son type MIME ('text/html') n'est pas exécutable, et que la vérification stricte du type MIME est activée".

15voto

Sitaram Points 51

Au lieu d'inclure votre js dans l'extension de fichier index.html vous pouvez l'inclure dans .angular-cli-json fichier.

Voici les étapes que j'ai suivies pour que cela fonctionne :

  1. Commencez par inclure vos données externes js dans assets/js
  2. Sur .angular-cli.json - ajoutez le chemin du fichier sous les scripts : [../app/assets/js/test.js]
  3. Dans le composant où vous souhaitez utiliser les fonctions de l'option js fichier.

Déclarez en haut de la page où vous voulez importer les fichiers en tant que

declare const Test:any;

Après cela, vous pouvez accéder à ses fonctions comme par exemple Test.add()

0 votes

Bonjour, pouvez-vous me dire où mettre la partie "Declare const Test:any ;" ? à l'intérieur du composant ? J'ai essayé de la mettre à l'intérieur de la classe d'exportation, et aussi avant la "classe d'exportation...." mais cela n'a pas fonctionné.

0 votes

Dans votre fichier app.component.ts ou dans n'importe quel fichier component.ts où vous voulez appeler la méthode de Test, il suffit d'ajouter "Declare const Test:any" en haut, là où vous importez les autres dépendances de ce composant.

0 votes

declare pas Declare

6voto

PeteZaria Points 99

L'approche suivante a fonctionné dans Angular 5 CLI.

Pour des raisons de simplicité, j'ai utilisé une démo similaire de d3gauge.js créée et fournie par oliverbinns - que vous pouvez facilement trouver sur Github.

Donc d'abord, j'ai simplement créé un nouveau dossier nommé JS externe au même niveau que le actifs dossier. J'ai ensuite copié les 2 fichiers .js suivants.

  • d3.v3.min.js
  • d3gauge.js

J'ai ensuite fait en sorte de déclarer les deux directives liées dans le fichier main index.html

<script src="./externalJS/d3.v3.min.js"></script>
<script src="./externalJS/d3gauge.js"></script>

J'ai ensuite ajouté un code similaire dans un jauge.component.ts comme suit :

import { Component, OnInit } from '@angular/core';

declare var d3gauge:any; <----- !
declare var drawGauge: any; <-----!

@Component({
  selector: 'app-gauge',
  templateUrl: './gauge.component.html'
})

export class GaugeComponent implements OnInit {
   constructor() { }

   ngOnInit() {
      this.createD3Gauge();
   }

   createD3Gauge() { 
      let gauges = []
      document.addEventListener("DOMContentLoaded", function (event) {      
      let opt = {
         gaugeRadius: 160,
         minVal: 0,
         maxVal: 100,
         needleVal: Math.round(30),
         tickSpaceMinVal: 1,
         tickSpaceMajVal: 10,
         divID: "gaugeBox",
         gaugeUnits: "%"
    } 

    gauges[0] = new drawGauge(opt);
    });
 }

}

et enfin, j'ai simplement ajouté un div dans le fichier correspondant gauge.component.html

<div id="gaugeBox"></div>

et voilà ! :)

enter image description here

2voto

Kamil Kiełczewski Points 6496

Vous pouvez aussi essayer ceci :

import * as drawGauge from '../../../../js/d3gauge.js';

et juste new drawGauge(this.opt); dans votre code ts. Cette solution fonctionne dans un projet avec angular-cli intégré à laravel sur lequel je travaille actuellement. Dans mon cas, j'essaie d'importer poliglot (btw : très bon pour les traductions) de node_modules :

import * as Polyglot from '../../../node_modules/node-polyglot/build/polyglot.min.js';
...
export class Lang 
{
    constructor() {

        this.polyglot = new Polyglot({ locale: 'en' });
        ...
    }
    ...
}

Cette solution est bonne car i n'ont pas besoin de COPIER tout fichier de node_modules :) .

UPDATE

Vous pouvez également regarder sur cette LISTE de manières d'inclure des librairies dans angular.

0 votes

Ça a marché pour moi :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X