2017-01-19 4 views
0

Mein TypeScript und normaler JavaScript-Code müssen einen Namespace und einige Daten teilen. TypeScript sollte einen Namespace "vorbereiten", externe JS stellt Daten bereit, TypeScript verarbeitet sie.Wie erstellt man einen globalen Namespace/eine Klasse in TypeScript, die in einfachem JavaScript verwendet werden kann?

Der Kontext ist eine Angular 2-Anwendung. Die Ladereihenfolge ist:

  1. Angular 2 App mit JavaScript startet
  2. eine benutzerdefinierte externen JavaScript-Datei dynamisch von einer externen Quelle (JSONP Stil)
  3. Angular 2 Anwendung kann die weitere Verarbeitung auf den erzeugten Daten geladen durch die geladene JS-Datei

Zeit im externen JavaScript-Datei mache ich so etwas wie diese:

if (typeof Blog === 'undefined') 
{ 
    Blog = { 
     Posts: [] 
    } 
} 
// ... 
Blog.Posts.push(post); 

In meinem Angular 2 app diese JavaScript-Datei wie diese wird dynamisch geladen und der Wert dann zugegriffen:

declare var Blog: any; 
... 
let firstPost = Blog.Posts[0]; 

Dies funktioniert, kann ich Daten von dem externen JS platziert zugreifen.

Jetzt möchte ich den JavaScript-Teil so minimal wie möglich halten. Also ich möchte die Deklaration Blog und Posts auf TypeScript verschieben, vorzugsweise so dass es dort stark typisiert verwendet werden kann.

So möchte ich meine JavaScript sah wie folgt aus:

// ... 
Blog.Posts.push(post); 

Beachten Sie die fehlende Deklaration von Blog. Ich habe so etwas in TypeScript versucht:

Aber anscheinend ist es nicht so einfach. Meine Angular 2 App stirbt bei mir mit einer allgemeinen Fehlermeldung ab. Der Fehler wird von Blog = new BlogClass() verursacht.

Gibt es Hinweise, wie Sie das lösen können?

+0

Was genau ‚generische Fehlermeldung‘ ist, und wie und wo BlogClass ist definiert? – artem

+0

@artem Egal, weil es wahrscheinlich falsch ist. Mein Mitnehmen ist bisher, dass diese deklarierte Variable nicht zugeordnet werden kann. Aber wenn das tatsächlich möglich ist, dann stehe ich korrigiert und da könnte alles deklariert werden, was dem JS-Namespace entsprechen würde. Ich versuchte es auch mit 'deklarieren var Blog: any' und dann' Blog = 1; 'was die gleiche Fehlermeldung gibt (mir zu sagen, dass es nicht erlaubt ist). Die Nachricht ist immer 'AUSNAHME: Die Eigenschaft kann nicht gesetzt' Nachricht 'von undefinierten oder Null-Referenz', wenn das hilft. –

+0

Oh. Es tut uns leid. Ich dachte, "die Deklaration von Blog in TypeScript verschieben" bedeutet, dass seine Definition (die eigentliche 'var Blog'-Anweisung, die globale Variable definiert) auf Javascript-Seite bleibt. Wenn dies nicht der Fall ist, entfernen Sie einfach 'declare' aus' var Blog' Zeile in Typoskript-Code. – artem

Antwort

2

declare bedeutet, dass die deklarierte Sache irgendwo anders definiert werden muss.

declare var Blog: BlogClass; 

produziert keinen Code in der resultierenden JavaScript aktivieren, damit diese Zuordnung

Blog = new BlogClass(); 

zur Laufzeit fehlschlägt, weil Blog existiert nicht.

Wenn Sie declare entfernen, wird diese Zeile in den generierten Code:

var Blog; 

Allerdings ist es nicht unbedingt var Blog in globalem Gültigkeitsbereich erstellen - wenn Sie Typoskript Code als Module kompilieren, wird es im Inneren ein erstellt werden Modul und wird für externen Javascript-Code nicht zugänglich sein, es sei denn, Sie gehen durch den Export von Typoskript-Modul und importieren dieses Modul in Ihrem JavaCSript-Code.

Die einfachste (aber ein bisschen schmutzig) Weg, um sicherzustellen, dass ein Objekt in globalem Gültigkeitsbereich erstellt wird, ist, dass explizit zu tun:

(window as any).Blog = new BlogClass(); 
Verwandte Themen