BPC Plugins entwickeln

Diese Seite beschreibt BPC Plugins.

Definition

Ein Plugin ist eine (ExtJS-)Komponente, die dafür ausgelegt ist, an diversen vorab definierten Stellen (Hooks) eingebunden zu werden.

Die Zuordnung von Plugin zum Verwendungsort ist dabei Aufgabe des BPC und kann nicht vom Plugin beeinflusst werden. Die Darstellung des Plugins am Verwendungsort (Hook) ist vom Hook abhängig. Dieser ist eine Sub-Klasse von Ext.Container und kann selbst über sein "Layout" bestimmen.

Lifecycle

Wird im BPC ein Modul bzw. eine Modulkomponente erzeugt, die ein Plugin-Hook enthält, dann wird zu diesem Zeitpunkt die Plugin-Konfiguration dieses Moduls (plugin_configuration) abgerufen. Alle dort konfigurierten Plugins werden dann über die createPlugin-Funktion an dem PluginInterface erzeugt (zunächst als ExtJS Konfiguration; das eigentliche Erzeugen geschieht dann implizit im Hook-Container). Dabei wird an das Plugin über das pluginConfiguration-Attribut ein Objekt mit Informationen über den Hook, den Modul-Kontext und optionaler Plugin-Konfiguration übergeben. Die Plugin-Komponenten bestehen so lange, bis diese explizit vom Hook entfernt werden oder der Hook selbst entfernt wird.

Beispiel Interface:
Ext.define("demo.PluginInterface", {
	extend : "BpcCommon.plugin.Interface",

	inheritableStatics : {
		NAME                  : "Demo Plugin",
		COMPONENT_XTYPE       : "demoPluginComponent",
		PLUGIN_ID             : "demo_plugin",
		DEFAULT_CONFIGURATION : {
			pluginMessage : "Messgage from the demo plugin"
		}
	}
});

Das Plugin Interface leitet(extend) von der Klasse BpcCommon.plugin.Interface ab. Dadurch wird dieses vom BPC als Plugin erkannt.

Folgende Attribute sollten gesetzt werden:

  • NAME: Der Name, der dem Benutzer in der Oberfläche angeboten wird.

  • COMPONENT_XTYPE : Referenz auf den alias der ExtJS Komponente, die gerendert werden soll.

  • PLUGIN_ID : Eineindeutige ID für das Plugin

  • DEFAULT_CONFIGURATION (optional): Standard Konfigurationsobjekt, die in der Oberfläche eingesehen und bearbeitet werden kann.

Beispiel Plugin Klasse
Ext.define("demo.Plugin", {
	extend : "Ext.Component",
	alias  : "widget.demoPluginComponent",
	html   : "Default Message",

	initComponent : function () {
		this.callParent();
		/*
         Checks whether a plugin configuration has been set and whether it contains a pluginMessage
        * If so, the pluginMessage is displayed as HTML
        * If not, the default HTML (“Default Message”) from the class is displayed
         *   */
		if (Ext.isDefined(this.pluginConfiguration) && Ext.isDefined(this.pluginConfiguration.configuration.pluginMessage)) {
			const htmlString = `<p>${  this.pluginConfiguration.configuration.pluginMessage} </p> `;
			this.setHtml(htmlString);
		}

		// Context information is available under `this.pluginConfiguration.context`
        // e.g., `pluginConfiguration.context.demoCounter`

        // Listener for refresh events from the hook
        this.pluginConfiguration.context.hook.on("refresh",this.onContextRefresh,this);
	},

	onContextRefresh: function (hook, newContextObj){
		// The new context information can be processed here
		// console.log(newContextObj.demoCounter);
	}

});

Das Attribut alias setzt sich aus "widget." und dem aus dem PluginInterface referenzierten COMPONENT_XTYPE zusammen. In diesem Fall "widget.demoPluginComponent". In der initComponent methode kann unter dem Attribut this.pluginConfiguration.configuration auf die Konfiguration des Plugins zugegriffen werden. Initial entspricht diese der DEFAULT_CONFIGURATION aus de, Plugin Interface. Diese kann jedoch in der Oberfläche bearbeitet werden (siehe Plugin konfiguration). So erstellte Plugins werden vom BPC automatisch erkannt und können Plugin-Fähigen Modulen (diese benötigen mindestens ein Hook) über die Konfiguration zugeordnet werden.

Hook bereitstellen

Damit ein Modul Plugins "empfangen" kann, muss dieses mindestens ein Hook bereitstellen. Diese müssen die HookContainer-Klasse erweitern und können an beliebigen Stellen im Modul, wie normale ExtJS Container eingesetzt werden. Dabei sollte es jedoch für jede "Stelle" ein eigenen Hook geben, da sonst die Zuordnung der Plugins problematisch ist. Die Hooks stehen dann am Modul für die Plugin-Zuweisung zur Verfügung.

Über das context Attribut können weitere Informationen oder Daten an die Plugins weitergereicht werden.

Beispiel Hook:
Ext.define("demo.PluginHook", {
	extend : "BpcCommon.plugin.HookContainer",
	alias  : "widget.demoPluginHook",

	layout : {
		type  : "hbox",
		align : "stretch"
	},


	inheritableStatics : {
		NAME    : "Demo Hook",
		HOOK_ID : "demo_hook",
		MODULE  : "demo"
	},

	context : {
		moduleId : "demo",
		demoCounter: 1
	},

	incrementCounter: function (){
		const me = this;

		me.context.demoCounter++;

		// The refresh function is implemented in BpcCommon.plugin.HookContainer and generates a “refresh” event
		me.refresh({
			demoCounter: me.context.demoCounter
		});

		// Alternatively, the following is also possible
		// me.refresh(me.context);
	}

});

Sollte sich an den Kontext-Informationen etwas ändern, können Plugins darüber informiert werden, in dem an der Hook-Komponente die Function refresh() mit den neuen Kontext-Informationen als Parameter aufgerufen wird. Dies ist im Beispiel Hook beispielhaft implementiert.

Damit Plugins die Informationen vom Hook erhalten, müssen diese einen Event-Listener für den Event refresh am Hook hinterlegen. Dies ist in der Beispiel Plugin Klasse exemplarisch implementiert.


Keywords: