Plain Javascript come servizio Angular 2

Devo aggiungere un file JavaScript di terze parti ospitato in un componente Angular 2. Questo file viene aggiornato ogni volta che viene apportata una modifica nel sistema proprietario dei fornitori di terze parti associato, quindi non posso semplicemente trascinarne una copia, includerla a livello locale e importarla nel progetto.

In genere includo questo file ad un livello superiore in un tag script, e quindi semplicemente uso declare : any per ottenere l’accesso ad esso. Tuttavia, in questo caso, poiché il componente stesso sta tentando di caricare lo script, non posso dichiarare la variabile di finestra perché non esiste sull’object finestra nel momento in cui viene caricato il componente, il che genera un errore.

Posso caricare lo script aggiungendo manualmente un tag script e questo funziona, tuttavia ho bisogno di accedere alla variabile della finestra che crea per poterlo usare correttamente. E non posso semplicemente usare un intervallo per cercarlo perché il typescript genera un adattamento che does not exist on object window .

C’è un modo che posso 1) Caricare il file JavaScript ospitato all’interno del componente, e 2) Ottenere l’accesso alla variabile di finestra creata dal file JavaScript caricato?

Aggiornamento 1: in base ai commenti, la soluzione precedente non sarà di aiuto.

Puoi farlo usando OpaqueToken in Angular2

1 . Creare un token che viene utilizzato per trovare un’istanza come di seguito in un file ts separato.

 import { OpaqueToken } from '@angular/core' export let name_of_The_Token = new OpaqueToken('name_Of_The_Window_Object'); 

2. Nel tuo App.module , devi importare e dichiarare una variabile che è il nome dell’object della tua finestra che rende il Token un servizio angular2 in modo che tu possa usare proprietà, metodi in quel file javascript attraverso i tuoi componenti.

 import { name_of_The_Token } from '/* file_Path */'; declare let name_Of_The_Window_Object : any; //below your import statements 

Passaggio 3: iniettarlo nella matrice di provider del modulo.

 { provide : name_of_The_Token , useValue : name_Of_The_Window_Object } 

Guida per utilizzare questo token nei componenti

  1. Importa il token come qualsiasi altro servizio e @Inject da angular-core

      import { name_of_The_Token } from '/* file_Path */'; import { Inject } from '@angular/core'; 
  2. Nel costruttore del componente

      constructor(@Inject( name_of_The_Token ) private _serviceObject : any ) 
  3. Qualsiasi dove nel tuo componente puoi usare le variabili e i metodi del tuo file javascript come

      this._serviceObject.method1() this._serviceObject.variable1 ..... 

Nota : uno svantaggio è che non otterrete intellisense .

Overcoming: Se stai cercando intellisense devi avvolgere i metodi e le variabili all’interno di un’interfaccia e usarlo nel tipo ** (invece di qualsiasi) ** del tuo token come

 export interface myCustom { method1(args): return_Type; method2(args): void; ..... } 

DEMO LIVE di ToasterService

In effetti, stai cercando di raccogliere una libreria javascript “modulo globale” da un CDN. (Presumo che la lib di terze parti non sia in CommonJS, AMD, UMD o altro formato di modulo, poiché è accessibile tramite un’unica variabile globale.)

Quindi la prima domanda è dove è il corrispondente file .d.ts? Contiene i nomi e le interfacce che informano Typescript della ‘forma’ della libreria, oltre a dichiarare che la variabile globale esisterà. Se la tua terza parte non lo fornisce, dovrai scriverlo da solo. Conterrà non solo la dichiarazione della variabile globale, come

declare var theGlobalVarInQuestion: IInterfaceOfStuffInsideLibrary;

ma anche la dichiarazione di detta interfaccia e le sue proprietà e i loro tipi, fino in fondo. In questo modo: https://github.com/catamphetamine/libphonenumber-js/blob/master/index.d.ts

Puoi includere il file .d.ts in / node_modules / @ types / nameOfSaidLibrary ma dovresti controllarlo nel repository di origine (con ansible ginnastica npm prune ), soprattutto perché un npm prune lo rimuoverà. Oppure, se lo metti altrove, modifica la proprietà typoot di typeroots per cercare sia in quella posizione che in quella normale / node_modules / @ types / folder.

Per essere chiari, il file .d.ts non crea (e non dovrebbe) effettivamente la variabile; dice solo che sarà lì quindi il compilatore Typescript non si lamenterà. Indipendentemente dal fatto che sia presente o meno in fase di esecuzione, tuttavia si sta caricando il js.

Se non lo stai caricando tramite il tag script nell’index.html, allora un’istruzione import Typescript nel componente che consuma può farlo (data la giusta configurazione di SystemJS o qualsiasi altra cosa tu stia utilizzando) o il componente che consuma può creare dynamicmente e aggiungi un nuovo tag script all’indice.html. Assicurati che il tuo caricatore di moduli non stia cercando di scaricarlo e lo impacchetti immediatamente con il resto della tua app in buildtime. Sembra che tu voglia scaricare nuovamente la lib ogni volta in fase di runtime.