JavaScript Module (ES Module)
TcHmi Framework Controls wurden bis zur Version 1.14 in sogenannten namespace entwickelt. Siehe Grundgerüst eines Controls.
namespace TcHmi.Controls {
export namespace FrameworkPrj1 {
export class FrameworkPrj1Control extends TcHmi.Controls.System.TcHmiControl {Diese Typescript-Syntax sorgt dafür, dass die Klasse zur Laufzeit im Browser unter TcHmi.Controls.FrameworkPrj1.FrameworkPrj1Control erreichbar ist.
Bei Controls ist das noch sinnvoll, jedoch sind genutzte Hilfsdateien oder Bibliotheken nur über globale Objekte möglich. Soll eine Funktion in eine eigene Datei auslagert werden, so muss diese Funktion in einen namespace wie TcHmi.Controls.FrameworkPrj1.sortArray erstellt werden und dieser dann genutzt werden.
Daher können seit Version 1.14 zusätzlich zu klassischen JavaScript auch JavaScript Module (ES Modules) genutzt werden.
Importe über relative Pfade
Hiermit kann eine neue Datei helper.ts erstellt werden. In dieser Datei wird die gewünschte Funktion mit dem Schlüsselwort export markiert.
export sortArray(arrayToSort: string[]) {
// implement
}Die Hilfsfunktion kann nun einfach im Control importiert werden und einfach genutzt werden:
import { sortArray } from './helper.js';Die Datei helper.js wird hier über einen relativen Pfad (relative specifiers) referenziert. Hier muss drauf beachtet werden, dass die Javascript-Datei referenziert wird, welche der Typescript-Compiler erstellt ('./helper.js' statt './helper.ts').
Importe über relative Schlüsselworte
Alternativ kann auch ein Import über ein Schlüsselwort (bare specifiers) erfolgen. Dies wird häufig genutzt, um externe Bibliotheken einzubinden. In einem Control könnte beispielsweise die marked Bibliothek genutzt werden.
import { marked } from 'marked';Damit der Browser später die Bibliothek laden kann, muss eine Referenz in der Manifest.json des Projektes erstellt werden. Daraus wird automatisch ein Eintrag in der zentralen importmap der Applikation erstellt.
"esmoduleImports": [
{
"imports": {
"marked": "FrameworkPrj1Control/Lib/marked.esm.js"
}
}
]Damit auch der Typescript-Compiler die volle Information über die Inhalte hat, sollte noch ein Eintrag in der tsconfig.tpl.json unter dem Punkt compilerOptions ergänzt werden:
"compilerOptions": {
"paths": {
"marked": ["./Lib/marked.esm.d.ts"]
}
}Paketübergreifende Exporte und Importe
Damit auch paketübergreifene Importe genutzt werden können, sind alle Package-Pfade in der zentralen importmap der Applikation referenziert. Viele Beckhoff-Pakete verfügen über die Datei index.esm.js im Wurzelverzeichnis als feste API für paket-globale Exporte.
Nur diese Datei sollte bei fremden Paketen importiert werden, da nur so sichergestellt werden kann, dass auch bei internen Refactoring die Exports weiterhin erreichbar bleiben.
Alle Controls, aber auch eine Code-Behind-Datei können so auf Funktionen des Paketes zugreifen.
import { ControlFactory } from "Beckhoff.TwinCAT.HMI.Framework/index.esm.js";
// …
let myButton = ControlFactory.createEx('TcHmi.Controls.Beckhoff.TcHmiButton', 'MyButton');Der Typescript-Compiler sollte auch hier über diese Pfade über compilerOptions in der tsconfig.tpl.json informiert werden.
"compilerOptions": {
"paths": {
"Beckhoff.TwinCAT.HMI.Framework/*": [ "$(Beckhoff.TwinCAT.HMI.Framework).InstallPath/*" ]
}
}$(Beckhoff.TwinCAT.HMI.Framework).InstallPath wird beim Speichern durch den richtigen Pfad ersetzt.
Dynamischer Import
Auch im klassischen JavaScript können Module mithilfe einer speziellen Syntax importiert werden. So ist bei Bedarf eine schrittweise Umstellung auf Module möglich.
import('Beckhoff.TwinCAT.HMI.Framework/index.esm.js').then(({ ControlFactory }) => {
let myButton = ControlFactory.createEx('TcHmi.Controls.Beckhoff.TcHmiButton', 'MyButton');
});![]() | Der Browser führt importierte Module nur einmal aus, auch wenn sie von mehreren Dateien importiert werden. Das bedeutet: Ein Export wie |
Beispiele
Ein vollständiges Beispiel-Projekt mit den wichtigsten Funktionen kann über die folgende Webseite eingesehen werden:
Siehe auch:
