AngularJS: Rekursive Templates

Rathes Sachchithananthan — 27.Jul.2015
in Web

Lange gab es in diesem Blog nichts mehr zu lesen. Der letzte Beitrag aus der Kategorie „Web“ ist sogar schon Anfang des Monat erschienen. Heute ist es aber  wieder so weit. Heute gibt es wieder einen Artikel. Dieses Mal das Thema: Wie stelle ich hierarchische Strukturen in einem AngularJS Template dar?

In den letzten Tagen bin ich sehr beschäftigt. Aktuell gibt es einen Sprint in der Entwicklung von fokus², welcher in Zusammenhang mit dem normalen Alltag viel Zeit und Energie in Anspruch nimmt. Die Arbeit nimmt auch die Zeit und Energie, die bisher in diesen Blog investiert wurde. Und auch weiterhin wird Zeit und Energie, die bisher für diesen Blog investiert wurden, in die Entwicklung von fokus² gesteckt. Falls jemand mich dabei unterstützen will, der kann sich gerne melden!

Diesen Blog werde ich aber nicht vergessen. Ich werde nach wie vor Beiträge veröffentlichen. Aber habt bitte Verständnis dafür, dass dies nicht mehr so regelmäßig stattfinden wird wie gewohnt. Bis die erste Version von fokus² steht, liegt der Fokus bei fokus² (Wortspiel ist keine Absicht gewesen, aber trotzdem habe ich gerade gelacht). Ich werde in dieser Zeit viel mehr einfach über die Entwicklung und Probleme, die während der Entwicklung auftauchen und hoffentlich geklärt werden, berichten. So auch hier.

Hierarchische Strukturen: Beispiel Navigation

Im aktuellen Sprint von fokus² befassen wir uns mit der Navigation und der Navigationsstruktur des Content-Management-Systems. Diese sind bei jedem gleich und man steht immer wieder vor der Frage wie man diese hierarchische Struktur angeht. Im Backend hatten wir das recht simpel gelöst und hatten so in unserer Frontend-Entwicklung folgende Struktur:

vm.elements = [{
 id: 1,
 title: "Startseite",
 parent_id: null,
 position: 0
}, {
 id: 2,
 title: "Seite",
 parent_id: null,
 position: 1,
 children: [{
 id: 3,
 title: "Unterseite",
 parent_id: 2,
 position: 0
 }]
}]

Diese Struktur soll in einer Liste dargestellt werden,  die der im Bild entspricht. (Beachtet, dass im Bild mehr Elemente vorhanden sind, als im Beispiel. Das Beispiel ist für die Erklärung des Prinzips stark vereinfacht).

Hierarchische Strukturen im AngularJS: Beispiel Navigationsstruktur
So soll mithilfe von AngularJS die Navigationsstruktur gerendert werden.

Fangen wir also ganz simpel an und bilden die oben beschriebene Struktur mit HTML und AngularJS Direktiven um.

<ul><li ng-repeat="element in elementController.elements">{{ element.title }}</li></ul>

Und weiter geht’s mit den Unterseiten:

<ul>
 <li ng-repeat="element in elementController.elements">
 {{ element.title }}
 <ul ng-if="element.children">
 <li ng-repeat="element in element.children">{{ element.title }}</li>
 </ul>
 </li>
</ul>

So. Hiermit hätten wir die Navigationsstruktur abgebildet. Das Problem: Was passiert, wenn die Navigationsstruktur noch tiefer geht? Das Bild zeigt ja schon die dritte Stufe und bei Online-Versand-Seiten sind es gerne mal noch tiefere Strukturen. Wenn es also noch weitergeht, dann muss man die immer weiter erstellen. Und selbst dann muss man die Tiefe kennen. Was aber, wenn man diese nicht kennt?

Die Lösung: Rekursive Templates

Wenn du dich mit Entwicklung beschäftigt, dann kanntest du sicher die Lösung des Problems: Rekursion. Man schreibt eine Funktion, die sich immer wieder selbst aufruft, bis ein Endereignis auftritt. Und bastelt sich so seine hierarchische Baumstruktur. Und genau das machen wir auch mit AngularJS. Es gibt in AngularJS die Möglichkeit inline Templates zu schreiben. Unsere Funktion, die sich immer wieder selbst aufrufen soll:

<script type="text/ng-template" id="elementTree">
    <ul ng-if="element.children.length != 0">
        <li ng-if="element.children" ng-repeat="element in element.children" ng-include="'elementTree'">{{ element.title }}</li>
    </ul>
</script>

Und dieses Template muss jetzt im richtigen HTML nur noch einmal ins Rollen gebracht werden.

<ul>
    <li ng-repeat="element in elementController.elements" ng-include="'elementTree'"></li>
</ul>

Ganz einfach oder nicht? Wir stoßen in der obersten Stufe mit einem ng-repeat alle Elternelemente an und geben diese auf und schauen bei jedem Durchlauf, ob diesem Element Kindelemente zugeordnet sind. Ist dies der Fall, dann bauen wir ein neues ng-repeat auf und laufen die Funktion also auch für das Kindelement ab. Einfach Rekursion, die dann endet, wenn wir alle Elemente einmal durch sind.

Ob AngularJS oder nicht: Problemfall Rekursion

Man konnte die Navigationsstruktur zwar mit Rekursion darstellen und das ging auch verdammt simpel, aber jeder, der sich mit Webentwicklung befasst hat, weiß, dass Rekursionen Ressourcen fressen. Und je tiefer und größer die Struktur wird, desto intensiver wird die Rekursion. Das sollte vermieden werden. Stattdessen lässt sich zum Beispiel das „Nested Set Model“ verwenden. Dieser Beitrag beschreibt sehr schön das „Nested Set Modell“ (englisch). Bei fokus² haben wir noch die rekursive Variante implementiert, da ich aufgrund der Erfahrung diese schneller umsetzen konnte. Außerdem gehen wir davon aus, dass jeder gute Webentwickler und Webdesigner weiß, dass man wegen der Usability nicht so tiefe Strukturen auf seiner Webseite abbildet.

Wir werden aber, sobald wir einmal online sind und alle Features quasi umgesetzt haben, das Nested Sets Modell auch für fokus² umsetzen, um so für potenzielle Shop-Plugins oder Ähnliches gute Grundlagen zu schaffen.

Ich hoffe, dass ich mit diesem Beitrag einigen helfen konnte. Vielleicht habe ich dir ja dabei helfen können das Problem mit Rekursionen im AngularJS Template zu lösen. Falls du Fragen hast, dann melde dich in den Kommentaren oder in den sozialen Netzwerken.

Rathes Sachchithananthan

Rathes Sachchithananthan

Hi, ich bin Rathes. Gründer dieses Blogs. Darüber hinaus habe ich Aheenam gegründet, eine Agentur für digitale Lösungen. Dort konzipiere und entwickle ich die digitale Weiterentwicklung meiner Kunden. Ich brenne für das Thema "Tamilen und Tamil Eelam" und bin ein Microsoft-Fanboy. Du findest mich auch auf diversen sozialen Netzwerken

Web und die Welt — Gott kann auch mal drin vorkommen

Ein Blog über das Web und die Welt. Wir schreiben über viele interessante Themen wie z.B. das Web, Tamil Eelam oder über Fotografie. Vielleicht ist auch was für dich dabei?