Denkanstoß in sachen Submenu

Pullmann

Erfahrenes Mitglied
Hallo ,

ich habe folgendes Problem und zwar brauche ich ein Submenu das beliebig viele Ebenen haben soll .

Main
-Subeins
--Subsubzwei
---Subsubdre
-Subzwei
--Subsubzwei


und so weiter ... es soll also so sein das jedes Submenu ein Submenu beinhalten kann !

Weis einer wie man sowas macht oder wonach ich suchen muss um das zu lösen
 
Mh ...

Wenn du das in Verbindung mit mySql machst würde ich jedem Menüeintrag eine Spalte 'parentID' oder so verpassen und da die ID des Menüpunktes speichern, dem, wie der Name schon sagt, der Menüpunkt zugeordnet ist.
Ist es ein Menüpunkt, welcher nicht einem anderen untergeordnet ist, einfach als 'parentID' eine 0 eintragen.

mfg mAu
 
Pullmann hat gesagt.:
Hallo ,

ich habe folgendes Problem und zwar brauche ich ein Submenu das beliebig viele Ebenen haben soll .

Main
-Subeins
--Subsubzwei
---Subsubdre
-Subzwei
--Subsubzwei


und so weiter ... es soll also so sein das jedes Submenu ein Submenu beinhalten kann !

Weis einer wie man sowas macht oder wonach ich suchen muss um das zu lösen
Also hierfür gibt es zwei verschiedene Methoden:

Die eine, an sich schnell und einfach umzusetzende Methode ist das Parent-ID-Modell. Du legst eine Tabelle mit mindestens 3 Spalten an:

- id (auto_increment)
- title (text für den jeweiligen menüpunkt)
- parent_id (übergeordneter menüpunkt)

So, alle Hauptmenüpunkte haben in der Spalte "parent_id" eine 0 stehen, d.h. alle diese Datensätze in der Datenbank sind an oberster Ebene in Menü angeordnet.

Also beispielsweise so:

Code:
+----+-------------+-----------+
| id | text        | parent_id |
+----+-------------+-----------+
| 1  | menü 1      | 0         |
+----+-------------+-----------+
| 2  | menü 2      | 0         |
+----+-------------+-----------+

Wenn Du jetzt dem Menü 1 weitere Untermenüpunkte zuordnen willst, musst Du allen diesen Datensätze als Parent-ID die ID vom Menüpunkt 1 zuordnen (in diesem Fall die 1). Das sieht dann in der Datenbank so aus:

Code:
+----+-------------+-----------+
| id | text        | parent_id |
+----+-------------+-----------+
| 1  | menü 1      | 0         |
+----+-------------+-----------+
| 2  | menü 2      | 0         |
+----+-------------+-----------+
| 3  | sub 1.1     | 1         |
+----+-------------+-----------+
| 4  | sub 1.2     | 1         |
+----+-------------+-----------+
| 5  | sub 1.3     | 1         |
+----+-------------+-----------+
Das gleiche kannst Du jetzt natürlich auch analog für den zweiten Menüpunkt machen. Nur musst dann natürlich die entsprechende ID vom zweiten Menüpunkt als Parent-ID abgespeichert werden. Diesen Untermenüpunkten kannst Du natürlich auch wiederum weitere Untermenüpunkte zuordnen. Einfach als Parent-ID die jeweilige ID vom gewünschten Untermenüpunkt, unter dem der weiter Untermenüpunkt (der 3. Ebene) zugeordnet werden soll, abspeichern.

So, und jetzt willst Du das ganze natürlich auslesen und darstellen. Du liest dann erstmal alle Hauptmenüpunkte aus der Datenbank, und lässt diese mittels einer Schleife ausgeben. Bei jedem Schleifendurchlauf musst Du jetzt allerdings wieder erneut eine SQL-Anfrage an die Datenbank schicken um zu prüfen, ob es für den jeweiligen Menüpunkt weitere Untermenüpunkte gibt, sprich: in einer rekursiven Funktion lässt Du dir Stück für Stück das Menü ausgeben. Und hier siehst Du auch schon den Nachteil bei dieser Methode. Hast Du nur ein kleines Menü mit einer überschaubaren Struktur, dann ist es kein Problem und das Menü sollte schnell ausgelesen werden. Wenn das Menü allerdings viele Haupt- und Untermenüpunkte enthalten soll, dann kann das ganze schon ordentlich auf die Performance gehen.

Als alternative dazu gibt es das NestedSet Modell. Hier is die Tabellenstruktur ein weniger trickreicher. In der Menütabelle hast Du nachwievor die Spalte "id" und die Spalte "title". Die Spalte "parent_id" fällt hier weg, dafür gibt es zwei neue Spalten: "left" und "right".

Wenn Du dir jetzt mal dein Menü (= Baum) vorstellst, so ist "Main" die Wurzel des Baumes (= Root). Dieser Wurzel werden jetzt nacheinader weitere Untermenüpunkte ( = Äste, bzw. Children) angefügt. Und hierbei kommen die beiden Spalten "left" und "right" ins Spiel. Diese Werte definieren, wie man durch den ganzen Baum gehen soll. Dabei legen diese Werte sowohl die Zuordnung verschiedener Äste (= Childens) fest, als auch deren Reihenfolge innerhalb des Astes.

Zugegeben, das ganze Prinzip ist auf den ersten Blick etwas komplitziert im vergleich zum Parent-ID Modell. Ein Bild [1] sagt mehr als Worte:

nestedsets4.gif


Aber auch diese Methode ist nicht perfekt: Da alle Werte in den "left" und "right" Spalten von einander abhängig sind, muss mann, wenn man einen weiteren Menüpunkt hinzufügen oder löschen will, unter umständen ALLE Datensätze aktualisieren. Aber dafür bietet das NestedSet Modell einen ganz klaren Vorteil: Mit nur einer einzigen SQL-Anfrage bekomme ich den kompletten Menübaum zurück inkl. dem jeweiligen Level (= Menüebene) des jeweiligen Menüpunktes. Somit liegt es auf der Hand, dass das NestedSet Modell den Vorteil beim Lesen hat. Wird die Menüstruktur oft geändert bzw. aktualisiert, muss man abwägen, ob der Einsatz von Nested Sets ebenfalls erforderlich ist.

Fazit: Man muss unbedingt abwägen, welches Modell das passende ist. Dabei spielt zum einen die Größe des Menüs und die Tiefe der Verschachtelung eine Rolle. Zum anderen sollte man aber auch beachten, ob dem Menü oft neue Menüpunkte hinzugefügt oder alte Menüpunkte gelöscht werden sollen.

[1] Das 'Nested Sets' Modell - Bäume mit SQL
 
KK danke erstmal !

das erste ist klar so macht man halt ein normales Submenu aber wie kann man dort eine unendliche Struktur aufbauen
Vieleicht mit zich geschachtelten Forschleifen ? Oder geht es auch anders?

Die NestedSet Modell erscheint mir das bessere zu sein ... werde mich da wohl mal reinfuchsen müssen !

Allerdings muss ich haufiger die Inhalte ändern was ja hier nicht so gut sein soll .

Also Danke
 
Zuletzt bearbeitet:
Pullmann hat gesagt.:
das erste ist klar so macht man halt ein normales Submenu aber wie kann man dort eine unendliche Struktur aufbauen
Vieleicht mit zich geschachtelten Forschleifen ? Oder geht es auch anders?
Nich tmit geschachtelten for-Schleifen.
Theoretisch ist eine while Schleife denkbar.
Aber an sich löst man das mit einer Rekursion.
Beispiel:
Code:
function menu(array eintraegeDieserEbene, int ebene) {
    foreach (eintraegeDieserEbene as eintrag) {
        eintrag ausgeben
        untereintraege ermitteln
        menu(untereintraege,ebene+1)
    }
}
hauptMenuePunkte ermitteln
menu(hauptMenuePunkte,0)
Wenn man den ersten Parameter etwas geschickt gestaltet lässt sich das auch ohne das Auslesen der Hauptmenüpunkte außerhalb der Funktion lösen.
Als Ausgabe mit einer html-Liste kann man sich evtl. auch den Parameter ebene sparen.
Beispiel:
Code:
function menu(int parentID) {
    eintraegeMitDieserParentID ermitteln
    foreach (eintraegeMitDieserParentID as eintrag) {
        eintrag ausgeben
        menu(eintrag['ID'])
    }
}
menu(0)
Gruß hpvw
 
Mit offen meine Ich das so

Das Menü sieht so aus :

-Link1
-Link2
-Link3

wenn ich jetzt z.B auf Link eins klicke sieht es so aus:

-Link1
--Link1.1
--Link1.2
-Link2
-Link3

wenn ich jetzt aber auf Link1.1 klicke schließt sich das Menü wieder und das Untermenü von den unteren Ebenen wird nicht angezeigt !

Das mein ich damit ... ich hatte es schon mal geschaft das ich bis in die 3 Ebene kam und das Menü auch offen blieb aber das war dann auch nicht sehr Dynamisch !

MfG Pullermann
 
Zuletzt bearbeitet:
Zurück