Toon posts:

[ASP NET] Recursieve menu structuur in lagen model

Pagina: 1
Acties:

Verwijderd

Topicstarter
In de context van een ASP NET internet applicatie, ben ik (onder meer) bezig met het opzetten van beheer functionaliteit van een menu (daarbij gebruik maken van een drie lagen model).

Hiervoor heb ik een 3-tier lagen model gekozen met de volgende lagen:
- Presentation Layer
- Business Logic Layer
- Data Access Layer

In mijn Data Access Layer haal ik mijn menu items in een simpele query op. Deze orden ik (op basis van de parentid) in een ArrayList en retourneer ik naar de Business Logic Layer.

De spannende dingen gebeuren in de Business Logic Layer. Hier heb ik (voorlopig ter test) in de Constructor een algoritme geprogrammeerd die gebaseerd is op een algoritme van EfBe in:

[rml]EfBe in "[ VB.NET] Treeview + Subnodes (van Subnod..."[/rml]

en dus de menu items plaatst in een Hashtable onder een key die gevormd wordt door het ID van het menuitem. Wanneer een menu item zijn parent ook in de Hashtable kan vinden, dan voegt het item zichzelf toe aan de sub menu items van de parent (hetgeen ook toevallig een Hashtable is :+ ).

Omdat ik de opgehaalde en reeds gekoppelde menu items uit deze Hashtable voor verschillende doeleinden wil gebruiken (te weten: een tree structuur van menu items en een horizontaal-uitklap-menu-structuur) heb ik meerdere methoden in deze Business Logic Layer beschikbaar gesteld die de gewenste structuur meegeven aan de Presentation Layer (deze methoden werken op basis van recursie).

Dit werkt allemaal perfect en is godsgruwelijk snel. Waarom, hoor ik je denken, post je dan in godsnaam je onzin in een topic. Welnu :) ... een Hashtable is een soortement van enorme zak, met daarin een verzameling objecten. Er is dus totaal geen sprake van structuur. De enige structuur die ik heb, is dat wanneer ik een menu item ophaal uit deze zak, ik weet welke menu items er onder hangen.

Wat ik feitelijk wil is een stukje structuur toe voegen, die de menu items in volgorde meegeeft aan de Presentation Layer. Met andere woorden, enerzijds wil ik de efficientie van een Hashtable gebruiken en anderzijds de ordelijkheid van een ArrayList.

Nu ben ik reeds bekend met een SortedList, dat zou ik eventueel kunnen gebruiken, maar ik zou graag de gedachten van mede-tweakers hierover willlen horen.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je zou ook gewoon 2 structuren bij kunnen houden. 1 Lijst voor de volgorde en de Hashtable voor het zoeken.

Als je snel elementen wilt kunnen zoeken en je kan aan de hand van het element ook al zijn plaats bepalen zou je ook iets van een binary tree kunnen gebruiken.

Mischien heb ik je post niet helemaal goed gelezen maar ik snap niet waarom je je child nodes van je tree in een Hashtable zou willen stoppen?

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-04 17:18
Kan je de values die zich in de Hashtable bevinden (Hashtable.Values) niet naar een Array omzetten (CopyTo), en dan die array sorteren mbhv de static method Sort van de Array. Die method heeft een overload die een IComparer als argument heeft.
Je kan dus je eigen IComparer schrijven, waarbij je dus zelf kunt opgeven hoe die sortering moet verlopen.

https://fgheysels.github.io/


  • rollebol
  • Registratie: Mei 2000
  • Laatst online: 22-08-2025
Het zou kunnen dat dit is wat je bedoelt:

http://www.codeproject.com/csharp/hashlistarticle.asp

  • joopst
  • Registratie: Maart 2005
  • Laatst online: 01-10-2024
ik zou je menu-item een extra property geven met sorteer-informatie.
op het moment dat je een setje menu-items uit je hashtable hebt gehaald kan je ze ff sorteren alvorens naar het scherm te printen.

Verwijderd

Topicstarter
@ RWB:
Dat zou inderdaad een optie kunnen zijn, bijvoorbeeld een Key-Value paar gebruiken waarbij Key de parentid is van het hoofd menu item waar het sub menu onder komt te hangen en Value de positie vormt. Ik zal dit eens gaan proberen.

Waarom ik ook de childs toevoeg aan de Hashtable, is omdat ik op het eerste niveau (aangenomen dat de hoofd menu items op het nulde niveau geplaatst zijn) een hoofd menu item nog wel kan vinden (hashtable[keyvalue parentid]). Echter, op een lager niveau zit het menu item verstopt in een submenu van een hoofd menu item

- HoofdItem (Item 1)
|_ SubMenuItem1.1 (met parent id 1)
|__ SubSubMenuItem1.1.1 (met perent id 1.1)

--> hoe vind ik parent id 1.1? (Die zit namelijk in de hashtable van van hoofditem met id 1.)

@ whoami:
Ik moet het volgende even uit het hoofd doen want ik weet niet meer precies hoe de methods van een Hashtable zijn opgebouwd.

Als ik je idee goed begrijp, zou je dat inderdaad kunnen doen. Echter, moet je dan niet voor alle Values van de Hashtable met menu items de sortering doen en (in mijn geval) ook voor ieder sub menu van ieder menu item? Want Values geeft een Enumerator terug, die met behulp van een Dictionray Entry is te doorlopen.

Terwijl ik dit schrijf, bedenk ik mij dat ik toch al elke sub menu aan het evalueren ben in die recursieve methoden, dus ik zou dan net zo goed de sortering op deze wijze mee kunnen nemen.

@ Rollebol:
Bedankt. Precies wat ik bedoel, kost me momenteel wel even wat veel tijd om dit door te lezen en het zelf te doen (en ja, waarom zouden we het wiel opnieuw uitvinden... omdat we natuurlijk Tweakers blijven :) ), maar zeker de moeite waard om eens door te lezen.

@Joopst:
Er zit reeds een property "Positie" in het Menu item object, echter, de sortering hiervan is waar ik momenteel tegenaan loop omdat er geen begin en geen eind is in een Hashtable.

  • whoami
  • Registratie: December 2000
  • Laatst online: 21-04 17:18
Verwijderd schreef op woensdag 07 december 2005 @ 10:47:
@ whoami:
Ik moet het volgende even uit het hoofd doen want ik weet niet meer precies hoe de methods van een Hashtable zijn opgebouwd.

Als ik je idee goed begrijp, zou je dat inderdaad kunnen doen. Echter, moet je dan niet voor alle Values van de Hashtable met menu items de sortering doen en (in mijn geval) ook voor ieder sub menu van ieder menu item? Want Values geeft een Enumerator terug, die met behulp van een Dictionray Entry is te doorlopen.
Hashtable.Values geeft een ICollection terug, en een ICollection heeft een ToArray method.

https://fgheysels.github.io/


Verwijderd

Topicstarter
Het heeft even geduurd, maar ik ben er nu pas aan toe gekomen. Voor de geïntresseerden, ik heb het comparer concept van whoami geïmplementeerd:

(Data Access Layer)
Alle menu items worden op volgorde van parent_id in een simpele query opgehaald en in een ArrayList opgeslagen die wordt doorgegeven aan de Business Logic Layer.

(Business Logic Layer (1))
Alle hoofd menu items in de ArrayList uit de Data Access Layer worden aan een Hashtable toegevoegd. Alle sub menu items worden aan het bijbehorende hoofd menu item toegevoegd. Om te bewerkstellingen dat ieder sub menu item zijn hoofd menu item altijd kan vinden (dus ook wanneer deze zich op een lager niveau bevindt) wordt elk sub menu item ook aan de Hashtable toegevoegd. Dit gebeurt momenteel in de constructor.

(Business Logic Layer (2))
Om een recursieve boomstructuur gegenereerd te krijgen, wordt de voorgenoemde Hashtable via de CopyTo() method naar een één-dimensionaal array geconverteerd. Middels een zelf gemaakte Comparer worden de menu items op basis van hun positie (die vooraf tijdens het toevoegen van een menu item wordt bepaald) gesorteerd. Middels het gesorteerde array wordt ieder menu item netjes in een Table gestopt, door het recursief aanroepen van deze methode wordt elk sub menu ook netjes onder het hoofd menu item gehangen.De uiteindelijke Table wordt meegegeven aan de Presentation Layer.

(Presentation Layer)
Toont de Table uit de Business Logic Layer waar nodig.
Pagina: 1