Versionen im Vergleich

Schlüssel

  • Diese Zeile wurde hinzugefügt.
  • Diese Zeile wurde entfernt.
  • Formatierung wurde geändert.
Auszug
hiddentrue

Nuclos Web Addon: Web Client erweitern, Angular, TypeScript, Node.js, npm, WEBCLIENT_SRC_DIR_FOR_DEVMODE, DEV-Modus, berechnete Felder.

globe with meridians Sprache: Deutsch · English

hammer and wrench Web Addon

Den Web Client per Angular/TypeScript erweitern – Dev-Setup, Live-Reload und ein Beispiel für berechnete Felder.

Status
colourPurple
titleHow-to
Status
colourBlue
titleAnwendungsentwickler
Status
colourGreen
titleStand: Jul 2026
Status
colourGrey
titlegilt fuer Nuclos 4.2026.x

Panel
bgColor#F4F5F7

Auf dieser Seite

Inhalt
maxLevel2
minLevel2

...

Was sind Web Addons?

Menüaufruf:

...

Konfiguration

...

Web Addon

...

.

Mit Web Addons

...

erweiterst du den Web Client flexibel per Angular/TypeScript – z.​B. um clientseitige Berechnungen in Unterformularen.

Voraussetzungen

...

  • Lokale Dev

...

  • -Instanz mit Node.js (ab 4.2024.x v18.20.2

...

  • ; davor v12)

...

  • z.

...

  • ​B. über nvm

...

  • , plus npm.
  • Editor (

...

  • z.

...

  • ​B. Visual Studio Code

...

  • ).
  • Nuclos-Server im DEV-Modus

...

Image Removed

Konfiguration auf eine Dev Instanz

  • .
Image Added

Web-Addon in der Verwaltung anlegen.

Lokale Entwicklung einrichten

  1. Addon anlegen und einem Nuclet zuweisen. Es liegt dann unter [instanz

...

  1. ]/data/webaddons-webclient-src/addons

...

  1. .

...

  1. Eine Kopie dieses Verzeichnisses anlegen (z.

...

  1. ​B. webaddons-webclient-src_) und den Parameter WEBCLIENT_SRC_DIR_FOR_DEVMODE

...

  1. darauf zeigen lassen; Serverneustart.
  2. In src

Image Removed

Image Removed

Image RemovedImage Removed

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.

...

  1. /assets/config.json

...

  1. die nuclosURL auf den lokalen

...

Image RemovedImage Removed

  1. Server setzen.
  2. Abhängigkeiten installieren und Dev-Server starten:
Codeblock
languagebash
npm install
npm run install-addon-deps
npm run start 

Jetzt müssen noch die npm Installationsskript im Order "webaddons-webclient-src_" ausgeführt werden (hier über das Terminal aus Visual Studio Code).

#npm install
#npm run install-addon-deps

Danach kann der lokale Server gestartet werden.

...

--webclient-host="127.0.0.1" --webclient-port=4200

Nachdem der Start abgeschlossen ist, kann die Seite über den Browser geöffnet werden.

Änderungen werden dank npm-Watcher direkt im Browser sichtbar. Fertige Anpassungen in der Web-Addon-Verwaltung ins Nuclet übernehmen und exportieren.

Image Added

Fertiges Addon ins Nuclet übernehmen.

Beispiel: Berechnete Felder

Ein globales Addon berechnet clientseitig Werte in Unterformularen. test_SubBo_refMainBo ist der BO-Name des Unterformulars; die Fachlogik steht in calculate_Attribute() und wird bei jeder Änderung der beobachteten Attribute aufgerufen.

Image Removed

Anpassungen die vorgenommen werden, werden direkt im genutzten Browser angezeigt. Sollen die Änderungen fertiggestellt sein können Sie in der Web Addon Verwaltung direkt in das Nuclet übernommen und dann exportiert werden.

Image Removed

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.

...

borderStylesolid
titleberechnete-felder.service.ts
linenumberstrue
Codeblock
languagetypescript
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;
}

Verwandte Seiten

package Nuclet


Nuclet.

Öffnen →

gear Regeln (clientseitig)


Clientseitig.

Öffnen →

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.