Sie zeigen eine alte Version dieser Seite an. Zeigen Sie die aktuelle Version an.

Unterschiede anzeigen Seitenhistorie anzeigen

« Vorherige Version anzeigen Version 2 Nächste Version anzeigen »

<Screenshot mit rotem Rahmen, wo die Funktion in der GUI zugänglich ist>


Draft

ab Nuclos 4.49.1

Überblick

Mit Web Addons kann man die Funktion des Web Clients flexibel erweitern. Neue Web Addons legt man unter Konfiguration → Web Addons an.

Voraussetzungen

  • Entwicklung auf einer lokalen Dev Instanz: NodeJS v14.17.6 (über z. B. nvm installieren), npm 6.14.15, Visual Studio Code (oder ein anderer Editor), Nuclos Server im DEV Modus installiert
  • Beispiel 1: NodeJS 12 auf dem Nuclos-Server

Entwicklung auf einer lokalen Dev Instanz

Das Addon muss wie o. g. angelegt werden, einem Nuclet zugewiesen sein (hier auch test). Danach ist es im Nuclos Installationspfad "[nuclos Instanzname]/data/webaddons-webclient-src/addons" zu finden.

Dieser Ordner kann jetzt z. B. mit Visual Studio Code (über Ordner öffnen) angezeigt werden:

Da aber eine lokale Entwicklung mit optischen Feedback im Browser möglich sein soll. Muss zusätzlich zur Development Installation noch ein Parameter (WEBCLIENT_SRC_DIR_FOR_DEVMODE) gesetzt werden. Dieser Parameter muss auf eine Kopie des Verzeichnisses "webaddons-webclient-src" verweisen (in diesem Beispiel "webaddons-webclient-src_") die vorher angelegt werden muss.

Nach einem Serverneustart stellt der Server das WebAddon jetzt aus dem neuen Verzeichnis zur Verfügung.
Zu erkennen ist  das - nachdem das Vereichnis "webaddons-webclient-src_" mit Visual Studio Code erneut geöffnet wurde - am verschobenen Addons Verzeichnis. Dies wird jetzt aus dem src Verzeichnis zur Verfügung gestellt.


Beispiel 1: Berechnete Felder

In diesem Fall legt man ein Web Addon z.B. mit dem Namen "BerechneteFelder" und der Option "global" an. Der Beispiel-Code erzeugt clientseitige Berechnung für Unterformulare.

berechnete-felder.service.ts
import { Injectable } from '@angular/core';
import {GlobalContext, ISubEntityObject, Logger} from "@nuclos/nuclos-addon-api";
import {
	IEntityObject,
	IEntityObjectDependents,
	IEntityObjectEventListener
} from "@nuclos/nuclos-addon-api/api/entity-object";

@Injectable({
	providedIn: 'root'
})

class CalculationRule {

	constructor(public attributeNames : string[], public targetAttributeName : string, public funcCalculate : (eo : IEntityObject, attributeName : string) => number) {
	}
}

@Injectable()
export class BerechneteFelderService {
	private attributeChangeListener : IEntityObjectEventListener;
	private selectedEo : IEntityObject;
	private calculationRules : CalculationRule[];

	callForDependents(eo : IEntityObject, func: {(entity:ISubEntityObject):void}) :any {
		eo.getDependents("test_SubBo_refMainBo").asObservable().subscribe(subEntities => {
			if( subEntities === undefined)
				return;
			for(let i in subEntities) {
				let entity : ISubEntityObject = subEntities[i];
				func(entity);
				this.logger.log('BerechneteFelder: onEoSelection() ' + func.prototype.name);
			}
		})
	}

	constructor(private addonCtx: GlobalContext, private logger: Logger) {
		this.logger.log('BerechneteFelder: constructor');
		this.calculationRules = [];
		this.calculationRules.push(new CalculationRule(["subbo_attribute1", "subbo_attribute2"], "subbo_attribute3", calculate_Attribute));
		this.attributeChangeListener = {
			afterAttributeChange: (entityObject: IEntityObject, attributeName: string, oldValue: any, newValue: any) => {
					this.logger.log("BerechneteFelder: entityObject: " + entityObject.getEntityClassId() + ", attributeName: " + attributeName +
						", oldValue: " + oldValue + ", newValue: " + newValue);
					this.calculationRules.forEach(calculationRule => {
						if(calculationRule.attributeNames.includes(attributeName)) {
							let result = calculationRule.funcCalculate(entityObject, attributeName);
							entityObject.setAttribute(calculationRule.targetAttributeName, result);
						}
					})
			}
		}

		addonCtx.getEntityObjectApi().onEoSelection().subscribe(eo => {
			this.logger.log('BerechneteFelder: onEoSelection()');
			if (this.selectedEo !== undefined) {
				this.selectedEo.getDependents("test_TestBo_ref1").asObservable().subscribe((entities => {
					entities?.forEach((subEo) => subEo.removeListener(this.attributeChangeListener));
				}))
			}

			if (eo !== undefined) {
				eo.getDependents("test_TestBo_ref1").asObservable().subscribe((entities => {
					entities?.forEach((subEo) => {
						subEo.addListener(this.attributeChangeListener)
					});
				}))
				this.selectedEo = eo;
			}
		})
		addonCtx.getEntityObjectApi().onEoModification().subscribe(eo => {
		});
	}
}

function calculate_Attribute(eo : IEntityObject, attributeName : string) : number {

	let dAttribute1 = eo.getAttribute("subbo_attribute1");
	let dAttribute2 = eo.getAttribute("subbo_attribute2");
	
	return dAttribute1 * dAttribute12;
}



test_SubBo_refMainBo ist der BO-Name des Unterformulars.

Die fachliche Implementierung findet in calculate_Attribute() statt. eo ist in diesem Fall eine Instanz des SubBos. Die Funktion wird bei jeder Änderung der Attribute subbo_attribute1 und subbo_attribute2 aufgerufen. Das Ergebnis wird in subbo_attribute3 geschrieben.

  • Keine Stichwörter