bIT_sosswald
Returning Responder

Snippets / Schnipsel Ausgabe einer Fremdschlüssel-Hierarchie

Jump to solution

Hallo Kolleginnen und Kollegen,

ich habe eine eigentlich ganz einfache Datenquelle wie im folgenden Bild. - Tags, die wiederum Kind-Tags haben können.

In den Snippets möchte ich nun als Extract die Parent-Chain anzeigen, so dass die Redaktion sehen kann in welcher Hierarchie die Tags sich befinden. Die Verschachtelung kann rein prinzipiell beliebig Tief sein.

Also so in etwa so: "Kategorie > Sub-Kategorie > Sub-Sub-Kategorie > Tag"

Für den direkten Parent habe ich dies schon hinbekommen, die komplette Chain bisher nicht. Mein aktuelles Ergebnis sieht wie folgt aus:

Das entsprechende Element dazu so:

424396_pastedImage_7.png

Den Parent habe ich jeweils über ein FS_DATASET im Formular eingebunden und greife in den Snippets wie folgt auf ihn zu: tt_parent.getDataset().getFormData().get(lang, "tt_name").get() + " > " + tt_name

Hat jemand eine Idee, wie man die komplette Parent-Chain bis zum obersten Element ausgeben kann?

Beste Grüße

Sandro

0 Kudos
1 Solution

Accepted Solutions
mbergmann
Crownpeak employee

Hi Sandro,

mit einem kleinen "Trick" geht es auch ohne Modul. Man kann den Abbildungsausdruck "fold()" für eine Art Schleife nutzen.

In meinem Beispiel funktioniert dann im Ausriss folgendes, wenn ich nichts übersehen habe passen meine Namen zu deinen, sollte also bei dir auch so funktionieren:

[1..10]

.fold(

  s:[tt_parent.dataset],

  x->if(s.last.formData.tt_parent.isEmpty,s,s.add(s.last.formData.tt_parent.dataset))

)

.map(x->x.formData.tt_name)

.reverse()

.toString(" / ")

Das ist quasi eine FOR-Schleife, die 10 Mal durchlaufen wird und sich die Hierarchie "hoch hangelt". Dabei wird das "s" mit dem aktuellen Elternelement initialisiert (Typ Dataset) und an diese Liste (die immer wieder als Eingabe "s" für den nächsten "Durchlauf" fungiert) wird so lange das Elternelement des letzten Elements angehangen, wie eines vorhanden ist - ansonsten wird das s aus dem vorherigen Durchgang unverändert weitergereicht. Das x nimmt hier immer den nächsten Wert aus der Liste an, also 1,2.3.4,...10 - wird aber hier im Rahmen des Lambdas gar nicht wirklich "benutzt".

Aus den fold() fällt also zunächst eine Liste von Dataset-Objekten heraus beginnend mit dem Elternelement des aktuellen Datensatzes, letztes Element ist dann der hierarchisch höchste. Das dann gemappt auf die Namen und einmal auf den Kopf gedreht und in einen einzelnen String mit Trennzeichen zusammengefasst - voilà.

Kleiner Nachteil: Man kann die Schleife nicht vorzeitig abbrechen, muss also hier einen einen sinnvollen Höchstwert finden (in meinem Beispiel 10), um nicht unnötig viele Iterationen zu machen.

Viele Grüße

Michael

View solution in original post

0 Kudos
6 Replies
hoebbel
Crownpeak employee

Hallo Sandro,

mir fällt da nur die sehr hässliche Methode ein, eine vorgegebene Anzahl an Ebenen manuell per if Statement zu prüfen, ob die Eingabekomponente dort gesetzt ist und wenn ja, die auszugeben.

Richtig unangenehm wird das dann noch, weil Du an der Datensatz-entfernten Seite anfangen willst mit der Ausgabe.

Du musst ja von der Datensatz-nahen Seite anfangen, die FS_DATASET Eingabekomponeten darauf zu prüfen, ob sie gesetzt ist und wenn ja, das formData des Datensatzes holen und darin wieder die FS_DATASET Eingabekomponente prüfen, ob sie gesetzt ist, den Datensatz holen ... und wenn Du die vorgegebene Anzahl an Ebenen erreicht hast, dann die Ausgaben entsprechend von innen nach außen durchführen.

Ich fürchte, dass wird ein sehr unübersichtlicher Code werden Smiley Sad

Sorry, ich hoffe, jemand anderes hat eine bessere Idee

Holger

0 Kudos

Hi Sandro,

in den Snippets kann man ja ganz normal Modulmethoden nutzen. Also kannst du auch ganz normal mit einer while-Schleife arbeiten und imemr wieder tt_parent abfragen bis du auf ein leeres Feld stößt. Oder verstehe ich dein Problem falsch?

Viele Grüße

Felix

0 Kudos

Hallo Felix,

hast du da evtl. ein Beispiel? if() in Snippets kenne ich, while habe ich bisher noch nicht gesehen / benutzt.

Grüße

Sandro

0 Kudos

Hi Sandro,

ich meinte damit, dass du Modulklassen (Library) nutzen kannst - also in einem FirstSpriit-Modul eine Funktion zum iterieren erstellen kannst.

Auf die kannst du ja per class() dann zugreifen

class("de.sandrospackage.util.ForeignKeyHierarchy").getDatasetPath(tt_parent.dataset);

Modulklasse ForeignKeyHierarchy:

public class ForeignKeyHierarchy {

     public static String getDatasetPath(Dataset dataset) {

         StringBuilder path = new StringBuilder();

         FormField<?> parent =  dataset.getFormData().get(null, "tt_parent");

         while (!parent.isEmpty()) {

            path.append(parent.getDataset().getFormData().get(lang, "tt_name").get());

            parent = parent.getFormData().get(null, "tt_parent");

         }

          return path.toString();

     }

}

Sowas in der Art eben Smiley Happy

0 Kudos
mbergmann
Crownpeak employee

Hi Sandro,

mit einem kleinen "Trick" geht es auch ohne Modul. Man kann den Abbildungsausdruck "fold()" für eine Art Schleife nutzen.

In meinem Beispiel funktioniert dann im Ausriss folgendes, wenn ich nichts übersehen habe passen meine Namen zu deinen, sollte also bei dir auch so funktionieren:

[1..10]

.fold(

  s:[tt_parent.dataset],

  x->if(s.last.formData.tt_parent.isEmpty,s,s.add(s.last.formData.tt_parent.dataset))

)

.map(x->x.formData.tt_name)

.reverse()

.toString(" / ")

Das ist quasi eine FOR-Schleife, die 10 Mal durchlaufen wird und sich die Hierarchie "hoch hangelt". Dabei wird das "s" mit dem aktuellen Elternelement initialisiert (Typ Dataset) und an diese Liste (die immer wieder als Eingabe "s" für den nächsten "Durchlauf" fungiert) wird so lange das Elternelement des letzten Elements angehangen, wie eines vorhanden ist - ansonsten wird das s aus dem vorherigen Durchgang unverändert weitergereicht. Das x nimmt hier immer den nächsten Wert aus der Liste an, also 1,2.3.4,...10 - wird aber hier im Rahmen des Lambdas gar nicht wirklich "benutzt".

Aus den fold() fällt also zunächst eine Liste von Dataset-Objekten heraus beginnend mit dem Elternelement des aktuellen Datensatzes, letztes Element ist dann der hierarchisch höchste. Das dann gemappt auf die Namen und einmal auf den Kopf gedreht und in einen einzelnen String mit Trennzeichen zusammengefasst - voilà.

Kleiner Nachteil: Man kann die Schleife nicht vorzeitig abbrechen, muss also hier einen einen sinnvollen Höchstwert finden (in meinem Beispiel 10), um nicht unnötig viele Iterationen zu machen.

Viele Grüße

Michael

0 Kudos

Hallo Michael,

VIELEN DANK!

Copy & Paste und es funktioniert einwandfrei. Mehr als 10 Ebenen wird es vermutlich sowieso nicht geben. Aktuell sind es 3. 😉

Beste Grüße
Sandro