Seam & Navigationsprobleme

Hallo

Ich habe ein Problem bei der Programmierung einer Webapplikation mithilfe von Seam.

Erstmal generell: Zum Verlinken benutze ich den s:buttons.

Ein typischer UseCase wäre z.B.

Objektliste wird aufgerufen. Aus dieser Liste wird ein Objekt (nennen wir es A) ausgewählt und in der Detailview geöffnet. Hier wird im Button das Attribut propagation auf „begin“ gesetzt. Ein Parameter cameFrom wird in der URL mit übergeben (in der Url würde das dann z.b. als cameFrom=AList stehen), sodass die Detailview beim zurück navigieren weiss woher sie kam. Auf die Detailview leite ich dann mit view=/ADetail weiter

Nun hat Objekt A weitere Unterkomponenten (B). Soll eine dieser Unterkomponenten bearbeitet werden, dann wird das Attribut propagation auf „nest“ gesetzt und der Parameter cameFrom wird mit der aktuellen view überschrieben (also steht in der URL dann cameFrom=ADetail).

Das gleiche Mache ich nun mit einer Unterkomponente © von Objekt B.

Sowohl A,B als auch C haben eine Listen ansicht in der man sich alle Objekte des Typs anzeigen lassen kann. Auf diese Listview wird verlinkt wenn das Attribut „cameFrom“ leer ist.

Nun möchte ich Schritt für Schritt mit den s:buttons den gleichen Weg wieder zurück gehen.

Dafür verwende ich ebenfalls s:buttons indenen das Attribut propagation auf „end“ gesetzt wird, damit die mit „nest“ geöffnete „Unterpropagation“ beendet wird und in die übergeordnete zurück gewechselt wird.

Wenn ich nun nach B zurück navigieren möchte funktioniert das auch wunderbar, da das Attribut cameFrom ja noch gesetzt ist und auf BDetail steht.

Wenn ich nun aber von BDetail auf ADetail wecheln will funktioniert das nicht da ich in der URL (und auch anscheinden (?)nirgends sonst) das Attribut cameFrom habe. Somit ist cameFrom leer und ich werde auf BList geleitet.

Eigentlich dachte ich, dass solche Attribute in der propagation zwischengespeichert werden. Dem scheint ja nicht so zu sein.

Jetzt frage ich mich allerdings wie ich eine solche Navigation verwirklichen kann.

Natürlich könnte ich jetzt einen weiteren Parameter übergeben der die vorherige URL einspeichert. Aber da diese Applikation ziemlich groß und verzweigt ist, müsste ich theoretisch gesehen unendlich viele Parameter mit in die URL geben, da man (fast) von jedem Startpunkt aus überall hin gelangen kann und der Benutzer ja nicht ein Objekt speichert und dann den Navigationspfad von vorne beginnt.

Mir fällt momentan kein Weg ein wie ich das verwirklichen kann. Ich hoffe ihr könnt mir mit ein paar Lösungsansätzen helfen.

Ich hoffe ich habe mich halbwegs verständlich ausgedrückt, wenn nicht einfach Fragen…

Schonmal vielen Dank im voraus

Grüße

Hallo,

Jetzt frage ich mich allerdings wie ich eine solche Navigation
verwirklichen kann.

Natürlich könnte ich jetzt einen weiteren Parameter übergeben
der die vorherige URL einspeichert. Aber da diese Applikation
ziemlich groß und verzweigt ist, müsste ich theoretisch
gesehen unendlich viele Parameter mit in die URL geben, da man
(fast) von jedem Startpunkt aus überall hin gelangen kann und
der Benutzer ja nicht ein Objekt speichert und dann den
Navigationspfad von vorne beginnt.

Mir fällt momentan kein Weg ein wie ich das verwirklichen
kann. Ich hoffe ihr könnt mir mit ein paar Lösungsansätzen
helfen.

Zunächst vorweg: Ich habe zwar schon viel mit Webapplikationen in Java gemacht, aber mit Seam hab ich noch nie was gemacht.

Also, du möchtest ja quasi tracken, über welchen Weg der Benutzer zu einer bestimmten Ansicht kam, damit du ihn mit „Zurück“-Buttons genau so wieder zurück leiten kannst. Logischerweise benötigst du dafür jeweils die Vorgängerseite der aktuellen Seite. Nachdem dein vorheriges cameFrom Attribut nicht mehr zur Verfügung steht, scheint dieser Weg ja nicht zu klappen.

Weitere zusätzliche Attribute einzuführen macht natürlich auch keinen Sinn, weil du u.U. extrem viele brauchst. Aber kannst du in einem Attribut nicht einfach eine Liste ablegen?

Also ich vermute mal dass „Attribute“ sowas wie Request oder Session-Variablen in „normalen“ Java WebApps sind. Ich würde einfach in einer Session-Variable/Attribut einen Stack (java.util.Stack) speichern. Bei jedem Weiterleiten wirfst du die Seite von der weitergeleitet wurde auf den Stack drauf. Damit hast du eine Art „History“ der Seiten-Aufrufe, in dem die Vorgaengerseite ganz oben am Stack liegt, die Vor-Vorgängerseite darunter usw usf…

Für den Zurück-Button verwendest du dann den obersten Eintrag des Stacks (ohne ihn zu entfernen). Erst wenn der Benutzer den Button klickt und zurück geleitet wird, entfernst du den obersten Eintrag vom Stack. Dann ist der Vor-Vorgänger nach dem Zurückleiten ganz oben und das Spiel beginnt von Neuem.

Hallo

Also erstmal vielen Dank für die Antwort.

Das wäre einge Möglichkeit.

Das heißt also

AList macht den Stack auf und übergibt in in BDetail, BDetail erweitert ihn und übergibt ihn in CDetail usw usw, wenn ich wieder auf eine Liste komme leere ich den Stack einfach wieder und beginne das Spiel von neuem.

Ich werde das mal im Team als Lösungsweg vorschlagen :smile:

Nochmal vielen Dank

AList macht den Stack auf und übergibt in in BDetail, BDetail
erweitert ihn und übergibt ihn in CDetail usw usw, wenn ich
wieder auf eine Liste komme leere ich den Stack einfach wieder
und beginne das Spiel von neuem.

Nö, bei jedem Schritt zurück nimmst du einfach den obersten Eintrag im Stack runter.

Ausgangssitutation:
Am Anfang bist du auf AList.
Der Stack ist leer.

Schritt 01:
Der Benutzer wechselt nach ADetail:
Jetzt legst du AList auf den Stack, da das die Seite ist von der du zu ADetail gekommen bist.
Inhalt des Stacks nun: [AList]

Schritt 02:
Der Benutzer wechselt von ADetail nach BDetail:
Jetzt legst du ADetail auf den Stack, da das die Seite ist von der du zu BDetail gekommen bist.
Inhalt des Stacks nun: [AList,ADetail]

Schritt 03:
Der Benutzer wechselt von BDetail nach CDetail:
Jetzt legst du BDetail auf den Stack, da das die Seite ist von der du zu CDetail gekommen bist.
Inhalt des Stacks nun: [AList,ADetail,BDetail]

Schritt 04:
Der Benutzer ist auf CDetail und klickt auf „Zurück“ und will damit zur vorherigen Ansicht (BDetail) wechseln. Jetzt nimmst du das oberste Elemente vom Stack (BDetail) und leitest zu dieser Ansicht weiter. Der Benutzer kommt damit zur BDetail-Seite und der
Inhalt des Stacks ist nun: [AList,ADetail]

Schritt 05:
Der Benutzer ist jetzt auf BDetail und klickt wieder auf „Zurück“ und will damit nochmals zur vorherigen Ansicht (ADetail) wechseln. Jetzt nimmst du wieder das oberste Elemente vom Stack (ADetail) und leitest zu dieser Ansicht weiter. Der Benutzer kommt damit zur ADetail-Seite und der
Inhalt des Stacks ist nun: [AList]

Schritt 06:
Der Benutzer ist jetzt auf ADetail und klickt wieder auf „Zurück“ und will damit nochmals zur vorherigen Ansicht (AList) wechseln. Jetzt nimmst du wieder das oberste Elemente vom Stack (AList) und leitest zu dieser Ansicht weiter. Der Benutzer kommt damit zur AList-Seite und der
Inhalt des Stacks ist nun: [] (also leer)

Nun gehts nicht mehr weiter zurück, weil du wieder am Ausgangspunkt bist.

Also bei jedem Schritt vor: Ein Element auf den Stack hinzufügen.
Bei jedem Schritt zurück: Ein Element runternehmen.

Den Stack leeren brauchst du nur, wenn die History für dich keine Relevanz mehr hat, also z.B. wenn der Benutzer zu einer komplett anderen Liste wechselt und du damit einen komplett neuen Ausgangspunkt für das „Zurück“ haben willst.