Properties dynamisch erzeugen, in C++
Beispielmodul: hellodyn.
loadOstPropertiesFromFile() ist nur eine Komfortfunktion: Sie ruft für jede Property und jedes Element der JSON-Datei genau dieselben Primitiven auf, die ein Modul selbst jederzeit während seiner Lebensdauer direkt aufrufen kann — bei der Instanziierung oder auch später, als Reaktion auf eine Benutzeraktion.
Eine Property manuell aufbauen
OST::PropertyMulti *pm = new OST::PropertyMulti(
"hello", "Hello", OST::Permission::ReadOnly,
/* level1 */ "", /* level2 */ "", /* order */ "1",
/* hasProfile */ false, /* hasGrid */ false);
createProperty(pm);
OST::ElementString *message = new OST::ElementString("message", "Message", "1", "");
message->setValue("Hello, world!");
pm->addElt(message);Der Konstruktor von PropertyMulti nennt seine beiden Hierarchie-Parameter level1/level2 (und das ist auch der Name, der dem Client im JSON-Dump zurückgegeben wird). Aber der JSON-Schlüssel einer .json-Datei eines Moduls ist devcat/group, nicht level1/level2 — zwei unterschiedliche Namen für dieselbe Sache, je nachdem, ob man C++ oder JSON schreibt. Eine leicht zu machende Verwechslung.
Jeder Elementtyp hat dasselbe Konstruktor-Schema: ElementXxx(clé, libellé, ordre, info-bulle). addElt() muss nach createProperty() aufgerufen werden.
Für ElementInt/ElementFloat werden die numerischen Beschränkungen (min/max/step/format — dieselben Schlüssel wie in JSON, siehe Der Typenkatalog) nach der Konstruktion über eigene Setter festgelegt:
OST::ElementFloat *step = new OST::ElementFloat("step", "Step size", "2", "");
step->setMinMax(1.0, 1000.0, false);
step->setStep(1.0, false);
step->setFormat("%.0f", false);
pm->addElt(step);Das letzte Argument (hier false) ist dasselbe emitEvent wie bei setValue() — es lohnt sich nicht, den Client über eine Metadatenänderung zu informieren, wenn das Element auf der Frontend-Seite noch gar nicht existiert.
Eine Property auf Anfrage erzeugen, nicht beim Start
Ein Button (ElementBool, directedit:true) kann die Erzeugung auslösen, statt sie beim Start durchzuführen:
void HelloDyn::onExternalEvent(OST::ExtEvent event)
{
if (event.ev != OST::ExtEvType::SV || event.prpkey != "actions") return;
if (event.eltkey == "create")
{
if (!getStore().contains("hello"))
{
OST::PropertyMulti *pm = new OST::PropertyMulti("hello", "Hello",
OST::Permission::ReadOnly, "", "", "2", false, false);
createProperty(pm);
OST::ElementString *message = new OST::ElementString("message", "Message", "1", "");
message->setValue("Hello, world! (créé à la demande)");
pm->addElt(message);
}
getEltBool("actions", "create")->setValue(false, true);
}
}Jeder Zweig setzt seinen eigenen Button nach der Verarbeitung der Aktion wieder auf false zurück — ein Aktions-Button ist ein einmaliger Auslöser, kein dauerhafter Schalter.
Ein Element zu einer bereits existierenden Property hinzufügen oder entfernen
if (event.eltkey == "addfield")
{
OST::ElementString *field = new OST::ElementString(key, label, "", "");
field->setValue(value);
getProperty("hello")->addElt(field);
}
if (event.eltkey == "removefield")
{
getProperty("hello")->deleteElt(key);
}addElt()/deleteElt() benachrichtigen den Client über die Änderung (ein neues Element erscheint oder verschwindet, ohne dass ein Neuladen der Seite nötig ist).
PropertyMulti nummeriert seine Elemente nicht selbst — es ist Aufgabe des Moduls, eindeutige Schlüssel zu erzeugen (zum Beispiel einen Zähler), um zu wissen, welche existieren und in welcher Reihenfolge sie entfernt werden sollen.