Zum Hauptinhalt springen

Deskriptoren und Primitive

Fast alles, was die Anwendung Ihnen anbietet – ein Menüeintrag, eine Schaltfläche, ein Assistent, der Schreibvorgang beim Klick auf Fertigstellen – ist eine Deklaration und kein Code. Die generische Laufzeit liest diese Deklarationen und erledigt die Arbeit. Deshalb kann ein Capability-Paket einer laufenden Installation einen Assistenten hinzufügen, ohne dass etwas neu gebaut wird.

Zwei Schichten, die man auseinanderhalten sollte:

Ein Deskriptor sagt, wo eine Aktion erscheint und was sie öffnet. Eine Transaktion sagt, was sie schreibt – als Liste von Schritten über einen festen Katalog von Primitiven.

Vom Deskriptor zum SchreibvorgangEin Deskriptor nennt einen Host, also wo er erscheint, und einen Handler, also was er öffnet. Ein Formular oder Assistent sammelt Eingaben und stoesst eine Transaktion an. Die Transaktion ist eine Liste von Schritten, die je eine Operation aus dem Katalog nennen. Jede Operation prüft ihre Eingabe und schreibt in einen Store.Descriptorid, Label, Icon, Reihenfolgehost – wo er erscheinthandler – was er öffnetHostein Kontextmenü, dieKopfleiste, ein Drawer,ein FormularabschnittHandleropenForm, openWizard,openDrawer, function,transactionTransactioneine geordnete Liste von Schritten;jeder nennt eine Operationund bildet die gesammelteEingabe darauf abOperationsdie Primitive: create,update, delete, set_alljede prüft ihre Eingabeund schreibt einen Store

Der Deskriptor​

Ein Deskriptor ist ein kleines JSON-Objekt. Dieser hier ist der Eintrag Show templates, den Sie an einem Knoten der Zeichenfläche benutzen:

{
"id": "entityCanvas.showTemplates",
"labelKey": "capabilities.showTemplates.label",
"fallbackLabel": "Show templates",
"icon": "LayoutTemplate",
"hosts": ["contextMenu:entityCanvas"],
"handler": { "kind": "function", "ref": "entity.showTemplates" },
"order": 65,
"separatorBefore": true,
"testId": "canvas-node-ctx-show-templates"
}

hosts ist, wo er erscheint. Ein Deskriptor kann mehrere nennen; so erreicht Sie dieselbe Aktion von der Zeichenfläche, aus dem Baum und aus der rechten Leiste, ohne dreimal geschrieben zu werden. Heute in Gebrauch sind unter anderem toolbar:main, contextMenu:entityCanvas, contextMenu:entityTree, contextMenu:groupTree, contextMenu:viewpointTree, contextMenu:entitySidebar und drawer:browse.

handler ist, was ein Klick bewirkt. Es gibt fünf Arten:

ArtÖffnet
openFormeinen Dialog, gebaut aus einer Felddeklaration
openWizardein mehrstufiges Formular
openDrawereinen der Browse-Drawer
functioneine benannte Funktion im Client
transactioneinen Schreibvorgang, ohne Dialog dazwischen

labelKey mit fallbackLabel heisst, dass ein Paket eigene Übersetzungen mitbringen kann und trotzdem etwas Sinnvolles anzeigt, wenn eine Sprache fehlt. order platziert den Eintrag zwischen seinen Nachbarn; testId ist, worüber die End-to-End-Tests ihn ansprechen.

Ein ungültiger Deskriptor wird übersprungen, nicht gemeldet

Deskriptoren werden beim Start der Registry gegen ein Schema geprüft. Einer, der durchfällt – ein falsch geschriebenes Feld, ein size, das das Schema nicht erlaubt – wird still verworfen, und das einzige Symptom ist ein Menüeintrag oder Assistent, der nie erscheint. Genau dafür trägt der Client einen Test, der jeden ausgelieferten Deskriptor parst.

Transaktionen und ihre Primitive​

Ein Assistent, der eine Entität, ihr Identifier-Attribut, drei Eigenschaftswerte und einen Knoten auf der Zeichenfläche anlegt, führt eine Transaktion mit fünf Schritten aus. Jeder Schritt nennt eine Operation – und die Operationen sind ein fester, geschlossener Katalog: heute 56 davon, als JSON neben der Laufzeit deklariert statt je Funktion geschrieben.

Sie sind danach gruppiert, was sie anfassen:

GruppeOperationen über
entity, entityGroup, nodeEntitäten, ihre Gruppen, ihre Platzierung auf einer Zeichenfläche
attributeAttribute, inklusive Anlegen-und-Verknüpfen und Umsortieren
relationBeziehungen zwischen Entitäten
viewpoint, viewpointTypeAnsichten und ihre Typen
entityType, attributeType, relationTypedas Vokabular
entityCustomProperty, attributeCustomProperty, relationCustomProperty, modelCustomPropertyDefinitionen benutzerdefinierter Eigenschaften
entityCPE, attributeCPE, relationCPE, modelCustomPropertyEntryWerte benutzerdefinierter Eigenschaften
jsonSchema, syncImport und Kommunikation mit dem Server

Jede Operation deklariert drei Dinge: welchen Store sie schreibt, welche Mutation sie ist und einen Eingabevertrag, gegen den sie vor dem Schreiben prüft.

MutationBedeutung
createeinen Datensatz hinzufügen
updateeinen ändern
deleteeinen entfernen
set_alleine ganze Menge zusammengehöriger Datensätze in einem Schritt abgleichen – für Eigenschaftswerte, wo „die, die Sie nicht geschickt haben" gelöscht werden müssen

Dieser Vertrag ist der Grund, warum eine Deklaration nicht stillschweigend Unsinn schreiben kann: ein Schritt, dessen Eingabe das Schema der Operation nicht erfüllt, wird abgewiesen – mit der Operations-Id in der Meldung.

Warum ein geschlossener Katalog

Ein Paket kann deklarieren, was geschrieben wird, in welcher Reihenfolge und aus welchen Eingaben – aber nicht, wie geschrieben wird. Alles geht durch dieselben geprüften Operationen, dieselbe Store-Schicht und dasselbe Journal; eine von einem Paket ergänzte Aktion ist also genauso rücknehmbar und nachvollziehbar wie eine eingebaute.

Weiterlesen​

  • Eigene Assistenten – ein durchgearbeitetes Beispiel: der Deskriptor, die Felder und die Transaktion hinter einem Assistenten, der ein Business Object anlegt.
  • Pakete – wie ein Capability-Paket installiert wird und warum die Anwendung danach neu laden muss.