Navigationsoptionen für SharePoint Online

Wichtig :  Dieser Artikel wurde maschinell übersetzt. Bitte beachten Sie den Haftungsausschluss. Die englische Version des Artikels ist als Referenz hier verfügbar: hier.

Dieser Artikel beschreibt, wie Sie die Seitenladezeiten für SharePoint Online durch eine strukturelle Navigation und suchgesteuerte Navigation verbessern können.

Die globale Navigation sowie die Abfragen, die zum Erstellen der strukturellen Navigation erforderlich sind, können zur Folge haben, dass Ihre Seiten in SharePoint Online langsamer geladen werden. Dies ist darauf zurückzuführen, dass jede dieser Abfragen eine andere Anforderung an den SQL-Server sendet. Für jede Ihrer Websites und Unterwebsites werden mehr Anforderungen an den SQL-Server gesendet. Dieses Problem betrifft auch die Gestaltungsvorlagen. Das bedeutet, dass auch die globale Navigation beeinflusst wird.

Einige SharePoint-Websites erfordern große oder komplexe Strukturen. Die sofort nutzbare strukturelle Navigation, bei der Inhalt nach Abfrage verwendet wird, kann langsame Seitenladezeiten zur Folge haben, da die Website über mehrere Ebenen verfügt. Durch jede der Ebenen von Unterwebsites wird eine weitere Abfrage erstellt.

Es gibt zwei Hauptnavigationsoptionen in SharePoint, die sofort verwendet werden können, sowie einen dritten benutzerdefinierten, suchgesteuerten Ansatz. Jede Option hat ihre Vor- und Nachteile, wie in der folgenden Tabelle beschrieben.

Strukturelle Navigation

Verwaltete Navigation

Suchgesteuerte Navigation

Vorteile:

  • Einfach zu konfigurieren

  • Sicherheitskürzung

  • Automatische Aktualisierung beim Hinzufügen von Websites

Vorteile:

  • Einfach zu verwalten

Vorteile:

  • Sicherheitskürzung

  • Automatische Aktualisierung beim Hinzufügen von Websites

  • Schnelle Ladezeiten und lokal zwischengespeicherte Navigationsstruktur

Nachteile:

  • Schlechte Leistung bei komplexer Websitestruktur

Nachteile:

  • Keine automatische Aktualisierung zur Abbildung der Websitestruktur

Nachteile:

  • Keine Möglichkeit, Websites einfach anzuordnen

  • Erfordert die Anpassung der Gestaltungsvorlage (technische Kenntnisse erforderlich)

Wenn Sie über eine Website mit einer Vielzahl von Unterwebsites verfügen und eine strukturelle Navigation verwenden, kann dies das Laden von Seiten deutlich verlangsamen. Welche Option für Ihre Website am besten geeignet ist, hängt von den Anforderungen an die Website und Ihren technischen Möglichkeiten ab. Wenn Sie sich sicher genug fühlen, eine benutzerdefinierte Gestaltungsvorlage zu verwenden, und über entsprechende Kapazitäten im Unternehmen verfügen, um die Änderungen zu verwalten, die unter Umständen an der Standardgestaltungsvorlage für SharePoint Online vorgenommen werden, resultiert die suchgesteuerte Option in einer bestmöglichen Benutzererfahrung. Wenn Sie einen einfachen Kompromiss zwischen der sofort nutzbaren strukturellen Navigation und Suche vorziehen, ist die verwaltete Navigation eine sehr gute Wahl. Die Option für die verwaltete Navigation kann durch Konfiguration verwaltet werden, erfordert keine Dateien zur Codeanpassung und ist deutlich schneller als die sofort nutzbare strukturelle Navigation.

Ein anderer Ansatz besteht darin, die vorhandene Website neu zu strukturieren und die Anzahl der erforderlichen Navigationselemente und Unterwebsites zu verringern, denn die strukturelle Navigation zeigt eine gute Leistung, solange die Struktur und Navigation der Website nicht allzu kompliziert sind.

In diesem Artikel werden die verschiedenen Ansätze anhand einer Beispielwebsitesammlung verglichen. Die Beispielwebsitesammlung verfügt über elf Unterwebsites, wobei jede Unterwebsite mindestens vier weitere Unterwebsites hat.

Screenshot mit Websites und Unterwebsites

Verwenden der strukturellen Navigation in SharePoint Online

Dies ist die sofort nutzbare Navigation, die standardmäßig verwendet wird. Sie ist in den meisten Fällen die einfachste und am besten geeignete Lösung. Sofern nicht eine komplexe Struktur mit mehreren Unterwebsites oder vielen Ebenen von Unterwebsites vorliegt, bietet sich die strukturelle Navigation an. Die Hauptvorteile dieses Ansatzes sind, dass eine Sicherheitskürzung erfolgt, dass bei Hinzufügen neuer Websites automatisch Aktualisierungen vorgenommen werden und keine Anpassungen der Gestaltungsvorlage erforderlich sind. Ein nicht technischer Benutzer kann auch einfach Elemente hinzufügen, ausblenden und die Navigation auf der Einstellungsseite verwalten.

Aktivieren der strukturellen Navigation in SharePoint Online

Im Folgenden wird die Leistung in einer SharePoint Online-Standardlösung mit struktureller Navigation und aktivierter Option zum Anzeigen von Unterwebsites veranschaulicht. Nachfolgend sehen Sie einen Screenshot mit den Einstellungen auf der Seite Websiteeinstellungen > Navigation.

Screenshot mit Unterwebsites

Analysieren der Leistung der strukturellen Navigation in SharePoint Online

Zum Analysieren der Leistung einer SharePoint-Seite verwenden Sie die Registerkarte Netzwerk der F12-Entwicklertools in Internet Explorer.

Screenshot mit F12 Entwickler Netzwerk Registerkarte "Tools"

Klicken Sie auf der Registerkarte Netzwerk auf die ASPX-Seite, die geladen wird, und klicken Sie dann auf die Registerkarte Details.

Screenshot mit der Registerkarte "Details"

Klicken Sie auf Antwortheader.

Screenshot der Details Registerkarte

SharePoint gibt einige nützliche Diagnoseinformationen in seinen Antwortheadern zurück. Einer der nützlichsten Werte ist SPRequestDuration   . Er gibt in Millisekunden an, wie lange die Verarbeitung einer Anforderung auf dem Server dauerte.

Im folgenden Screenshot ist Unterwebsites anzeigen für die strukturelle Navigation deaktiviert. Das bedeutet, dass in der globalen Navigation nur die Websitesammlungsverknüpfung vorhanden ist:

Screenshot, der Ladezeiten als Anforderungsdauer darstellt

Der Schlüssel SPRequestDuration    hat einen Wert von 245 Millisekunden. Dies steht für die Zeit, die für die Rückgabe der Anforderung erforderlich war. Da nur ein Navigationselement auf der Website vorhanden ist, ist dies ein guter Benchmark dafür, wie gut SharePoint Online ohne umfangreiche Navigation funktioniert. Der nächste Screenshot zeigt, wie sich das Hinzufügen in den Unterwebsites auf diesen Schlüssel auswirkt.

Screenshot mit einer Anforderungsdauer 2502 ms

Das Hinzufügen von Unterwebsites hat die für die Rückgabe der Seitenanforderung benötigte Zeit deutlich erhöht.

Die Vorteile der Verwendung der normalen strukturierten Navigation bestehen darin, dass Sie auf einfache Weise die Reihenfolge bestimmen, Websites ausblenden und Seiten hinzufügen können und dass die Ergebnisse sicherheitsgekürzt werden. Außerdem weichen Sie nicht von den unterstützten Gestaltungsvorlagen ab, die in SharePoint Online verwendet werden. Wenn Sie Ihre Website sorgfältig strukturieren und die Anzahl der Unterwebsites in der Websitesammlung minimieren, zeigt die strukturelle Navigation eine gute Leistung.

Verwenden der verwalteten Navigation und verwalteter Metadaten in SharePoint Online

Die verwaltete Navigation ist eine weitere sofort nutzbare Option, die Sie verwenden können, um die gleiche Art von Funktionalität wie bei der strukturellen Navigation neu zu erstellen.

Der Vorteil der Verwendung verwalteter Metadaten besteht darin, dass das Abrufen der Daten wesentlich schneller geht, als Inhalt nach Abfrage zu verwenden, um die Websitenavigation zu erstellen. Dies ist zwar wesentlich schneller, doch besteht keine Möglichkeit einer Sicherheitskürzung der Ergebnisse. Wenn also ein Benutzer keinen Zugriff auf eine bestimmte Website hat, wird der Link zwar noch angezeigt, führt aber zu einer Fehlermeldung.

So implementieren Sie die verwaltete Navigation und die Ergebnisse   

Es gibt mehrere Artikeln auf TechNet zu den Details der verwalteten Navigation, beispielsweise, finden Sie unter Übersicht über die verwaltete Navigation in SharePoint Server 2013.

Um die verwaltete Navigation implementieren zu können, benötigen Sie Administratorberechtigungen für den Terminologiespeicher. Durch Einrichten von Begriffen mit URLs, die der Struktur einer Websitesammlung entsprechen, kann die verwaltete Navigation anstatt einer strukturellen Navigation verwendet werden. Beispiel:

Screenshot mit dem Namen Subsite1 Beispiel

Das folgende Beispiel zeigt die Leistung der komplexen Navigation bei Verwendung der verwalteten Navigation.

Screenshot der SPRequestDuration Beispiel

Mithilfe der verwalteten Navigation lässt sich die Leistung im Vergleich zum Ansatz der strukturellen Navigation, bei der Inhalt nach Abfrage verwendet wird, konsistent verbessern.

Verwenden einer suchgesteuerten, clientseitigen Skripterstellung

Mithilfe der Suchfunktion können Sie die Indizes nutzen, die im Hintergrund anhand der kontinuierlichen Durchforstung aufgebaut werden. Das bedeutet, dass es keine übermäßig vielen Inhaltsabfragen gibt. Die Suchergebnisse werden aus dem Suchindex abgerufen, und die Ergebnisse werden sicherheitsgekürzt. Dies geht schneller als die Verwendung normaler Inhaltsabfragen. Durch Verwendung der Suchfunktion für die strukturelle Navigation, insbesondere dann, wenn Sie über eine komplexe Websitestruktur verfügen, lässt sich das Laden von Seiten erheblich beschleunigen. Der Hauptvorteil dieser verwalteten Navigation ist, dass Sie von der Sicherheitskürzung profitieren.

Dieser Ansatz umfasst das Erstellen einer benutzerdefinierten Gestaltungsvorlage und das Ersetzen des sofort nutzbaren Navigationscodes durch benutzerdefiniertes HTML. Gehen Sie folgendermaßen vor, um den Navigationscode in der Datei "seattle.html" zu ersetzen.

In diesem Beispiel öffnen Sie die Datei "seattle.html" und ersetzen das gesamte Element id="DeltaTopNavigation" durch den benutzerdefinierten HTML-Code.

Beispiel: Ersetzen Sie den Navigationscode Out-of-Box-auf einer Masterseite

  1. Navigieren Sie zur Seite Websiteeinstellungen.

  2. Öffnen Sie durch Klicken auf Gestaltungsvorlagen den Gestaltungsvorlagenkatalog.

  3. Von hier aus können Sie durch die Bibliothek navigieren und die Datei seattle.master herunterladen.

  4. Bearbeiten Sie den Code mit einem Texteditor, und löschen Sie den Codeblock im folgenden Screenshot.

    Screenshot vom zu löschenden DeltaTopNavigation-Code
  5. Entfernen Sie den Code zwischen den Tags <SharePoint:AjaxDelta id="DeltaTopNavigation"> und <\SharePoint:AjaxDelta>, und ersetzen Sie ihn durch den folgenden Codeausschnitt:

    <div id="loading">
      <!--Replace with path to loading image.-->
      <div style="background-image: url(''); height: 22px; width: 22px; ">
      </div>
    </div>
    <!-- Main Content-->
    <div id="navContainer" style="display:none">
        <div data-bind="foreach: hierarchy" class="noindex ms-core-listMenu-horizontalBox">
            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                <span class="menu-item-text" data-bind="text: item.Title">
                </span>
            </a>
            <ul id="menu" data-bind="foreach: $data.children" style="padding-left:20px">
                <li class="static dynamic-children">
                    <a class="static dynamic-children menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                        <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
                            <span class="menu-item-text" data-bind="text: item.Title">
                            </span>
                        </span>
                    </a>
                    <ul id="menu" data-bind="foreach: children; visible: children.length>0" class="dynamic" >
                        <li class="dynamic">
                            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                                <span class="menu-item-text" data-bind="text: item.Title">
                                </span>
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
  6. Ersetzen Sie die URL in das Laden Bild Anker-Tag am Anfang, mit einem Link zu einer beim Laden des Bilds in Ihrer Websitesammlung. Nachdem Sie die Änderungen vorgenommen haben, benennen Sie die Datei, und klicken Sie dann auf den Gestaltungsvorlagenkatalog hochladen. Dadurch wird eine neue Master-Datei generiert.

  7. Dieser HTML-Code ist das grundlegende Markup, das durch die vom JavaScript-Code zurückgegebenen Suchergebnisse gefüllt wird. Sie müssen den folgenden Code bearbeiten, um den Wert für var root = “site collection URL zu ändern, wie im folgenden Codeausschnitt gezeigt:

    var root = “https://spperformance.sharepoint.com/sites/NavigationBySearch”;

    Die gesamte JavaScript-Datei sieht wie folgt aus:

    //Models and Namespaces
    var SPOCustom = SPOCustom || {};
    SPOCustom.Models = SPOCustom.Models || {}
    SPOCustom.Models.NavigationNode = function () {
    
        this.Url = ko.observable("");
        this.Title = ko.observable("");
        this.Parent = ko.observable("");
    
    };
    
    var root = "https://spperformance.sharepoint.com/sites/NavigationBySearch";
    var baseUrl = root + "/_api/search/query?querytext=";
    var query = baseUrl + "'contentClass=\"STS_Web\"+path:" + root + "'&trimduplicates=false&rowlimit=300";
    
    var baseRequest = {
        url: "",
        type: ""
    };
    
    
    //Parses a local object from JSON search result.
    function getNavigationFromDto(dto) {
        var item = new SPOCustom.Models.NavigationNode();
        if (dto != undefined) {
    
            var webTemplate = getSearchResultsValue(dto.Cells.results, 'WebTemplate');
    
            if (webTemplate != "APP") {
                item.Title(getSearchResultsValue(dto.Cells.results, 'Title')); //Key = Title
                item.Url(getSearchResultsValue(dto.Cells.results, 'Path')); //Key = Path
                item.Parent(getSearchResultsValue(dto.Cells.results, 'ParentLink')); //Key = ParentLink
            }
    
        }
        return item;
    }
    
    function getSearchResultsValue(results, key) {
    
        for (i = 0; i < results.length; i++) {
            if (results[i].Key == key) {
                return results[i].Value;
            }
        }
        return null;
    }
    
    //Parse a local object from the serialized cache.
    function getNavigationFromCache(dto) {
        var item = new SPOCustom.Models.NavigationNode();
    
        if (dto != undefined) {
    
            item.Title(dto.Title);
            item.Url(dto.Url);
            item.Parent(dto.Parent);
        }
    
        return item;
    }
    
    /* create a new OData request for JSON response */
    function getRequest(endpoint) {
        var request = baseRequest;
        request.type = "GET";
        request.url = endpoint;
        request.headers = { ACCEPT: "application/json;odata=verbose" };
        return request;
    };
    
    /* Navigation Module*/
    function NavigationViewModel() {
        "use strict";
        var self = this;
        self.nodes = ko.observableArray([]);
        self.hierarchy = ko.observableArray([]);;
        self.loadNavigatioNodes = function () {
            //Check local storage for cached navigation datasource.
            var fromStorage = localStorage["nodesCache"];
            if (false) {
                var cachedNodes = JSON.parse(localStorage["nodesCache"]);
    
                if (cachedNodes && timeStamp) {
                    //Check for cache expiration. Currently set to 3 hrs.
                    var now = new Date();
                    var diff = now.getTime() - timeStamp;
                    if (Math.round(diff / (1000 * 60 * 60)) < 3) {
    
                        //return from cache.
                        var cacheResults = [];
                        $.each(cachedNodes, function (i, item) {
                            var nodeitem = getNavigationFromCache(item, true);
                            cacheResults.push(nodeitem);
                        });
    
                        self.buildHierarchy(cacheResults);
                        self.toggleView();
                        addEventsToElements();
                        return;
                    }
                }
            }
            //No cache hit, REST call required.
            self.queryRemoteInterface();
        };
    
        //Executes a REST call and builds the navigation hierarchy.
        self.queryRemoteInterface = function () {
            var oDataRequest = getRequest(query);
            $.ajax(oDataRequest).done(function (data) {
                var results = [];
                $.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function (i, item) {
    
                    if (i == 0) {
                        //Add root element.
                        var rootItem = new SPOCustom.Models.NavigationNode();
                        rootItem.Title("Root");
                        rootItem.Url(root);
                        rootItem.Parent(null);
                        results.push(rootItem);
                    }
                    var navItem = getNavigationFromDto(item);
                    results.push(navItem);
                });
                //Add to local cache
                localStorage["nodesCache"] = ko.toJSON(results);
    
                localStorage["nodesCachedAt"] = new Date().getTime();
                self.nodes(results);
                if (self.nodes().length > 0) {
                    var unsortedArray = self.nodes();
                    var sortedArray = unsortedArray.sort(self.sortObjectsInArray);
    
                    self.buildHierarchy(sortedArray);
                    self.toggleView();
                    addEventsToElements();
                }
            }).fail(function () {
                //Handle error here!!
                $("#loading").hide();
                $("#error").show();
            });
        };
        self.toggleView = function () {
            var navContainer = document.getElementById("navContainer");
            ko.applyBindings(self, navContainer);
            $("#loading").hide();
            $("#navContainer").show();
    
        };
        //Uses linq.js to build the navigation tree.
        self.buildHierarchy = function (enumerable) {
            self.hierarchy(Enumerable.From(enumerable).ByHierarchy(function (d) {
                return d.Parent() == null;
            }, function (parent, child) {
                if (parent.Url() == null || child.Parent() == null)
                    return false;
                return parent.Url().toUpperCase() == child.Parent().toUpperCase();
            }).ToArray());
    
            self.sortChildren(self.hierarchy()[0]);
        };
    
    
        self.sortChildren = function (parent) {
    
            // sjip processing if no children
            if (!parent || !parent.children || parent.children.length === 0) {
                return;
            }
    
            parent.children = parent.children.sort(self.sortObjectsInArray2);
    
            for (var i = 0; i < parent.children.length; i++) {
                var elem = parent.children[i];
    
                if (elem.children && elem.children.length > 0) {
                    self.sortChildren(elem);
                }
            }
        };
    
        // ByHierarchy method breaks the sorting in chrome and firefix 
        // we need to resort  as ascending
        self.sortObjectsInArray2 = function (a, b) {
            if (a.item.Title() > b.item.Title())
                return 1;
            if (a.item.Title() < b.item.Title())
                return -1;
            return 0;
        };
    
    
        self.sortObjectsInArray = function (a, b) {
            if (a.Title() > b.Title())
                return -1;
            if (a.Title() < b.Title())
                return 1;
            return 0;
        }
    }
    
    //Loads the navigation on load and binds the event handlers for mouse interaction.
    function InitCustomNav() {
        var viewModel = new NavigationViewModel();
        viewModel.loadNavigatioNodes();
    }
    
    function addEventsToElements() {
        //events.
        $("li.dynamic-children").mouseover(function () {
            var position = $(this).position();
            $(this).find("ul").css({ width: 125, left: position.left + 10, top: 50 });
    
        })
            .mouseout(function () {
                $(this).find("ul").css({ width: 0, left: -99999, top: 0 });
            });
    }
    
    _spBodyOnLoadFunctionNames.push("InitCustomNav");
    

    Zum Zusammenfassen vorhanden ist ein viewModel Objekt erstellt, und klicken Sie dann die loadNavigationNodes() Funktion auf das Objekt in der Funktion jQuery $(document).ready den oben aufgeführten Codes werden aufgerufen. Diese Funktion lädt entweder die zuvor erstellte Navigationshierarchie in HTML5 lokalen Speicher des Clientbrowsers gespeichert oder die Funktion queryRemoteInterface()aufgerufen.

    QueryRemoteInterface() erstellt eine Anforderung mithilfe der Funktion getRequest() mit dem Abfrageparameter, die zuvor im Skript definiert und gibt dann Daten aus dem Server zurück. Diese Daten sind im Wesentlichen ein Array von alle Websites in der Websitesammlung, die als durchstellen Datenobjekte mit verschiedenen Eigenschaften dargestellt. Diese Daten werden dann in der zuvor definierten SPO.Models.NavigationNode Objekte dem Knockout.js erstellen sichtbare Eigenschaften für die Verwendung von Daten, die die Werte in den HTML-Code, die wir zuvor definiert binden analysiert. Die Objekte werden dann in eine Ergebnisarray eingefügt. Diese Matrix ist in JSON erstellt mit analysiert und in der lokalen Browser-Speicher für verbesserte Leistung von zukünftigen Seite geladen gespeichert.

  8. Als Nächstes werden die Ergebnisse in der Matrix self.nodes zugewiesen und außerhalb der Objekte, die die Ausgabe einer Matrix self.heirarchyzuweisen linq.js mit eine Hierarchie erstellt wird. Diese Matrix ist das Objekt, das an den HTML-Code gebunden ist. In der Funktion toggleView() dazu das Self-Objekt für die Funktion ko.applyBinding() übergeben. Dadurch wird dann die Hierarchie Matrix an den folgenden HTML-Code gebunden werden soll:

    <div data-bind=”foreach: hierarchy” class=”noindex ms-core-listMenu-horizontalBox”>

    Schließlich werden die Ereignishandler für mouseenter und mouseexit zum der Navigation auf oberster Ebene der Unterwebsite Dropdownmenüs verarbeitet hinzugefügt, die in der Funktion addEventsToElements() abgeschlossen ist.

    Im folgenden Screenshot sehen Sie die Ergebnisse der Navigation:

    Screenshot der Ergebnisse der navigation

    In unserem komplexen Navigationsbeispiel zeigt das Laden einer leeren Seite ohne lokales Zwischenspeichern, dass die Zeit auf dem Server von der strukturellen Benchmarknavigation auf ein ähnliches Ergebnis reduziert wurde wie beim Ansatz der verwalteten Navigation.

    Screenshot des SPRequestDuration 301

    Ein wesentlicher Vorteil dieses Ansatzes ist, dass durch Verwendung des lokalen HTML5-Speichers die Navigation lokal für den Benutzer gespeichert wird, wenn er die Seite das nächste Mal lädt.

Durch Verwendung der Such-API für die strukturelle Navigation lassen sich wesentliche Leistungssteigerungen erzielen, doch müssen dafür einige technische Fähigkeiten zur Ausführung und Anpassung dieser Funktionen vorhanden sein. Bei der Beispielimplementierung werden die Websites auf die gleiche Weise angeordnet wie bei der sofort nutzbaren strukturellen Navigation, nämlich in alphabetischer Reihenfolge. Wenn Sie von dieser Reihenfolge abweichen möchten, ist dies komplizierter zu entwickeln und zu verwalten. Außerdem müssen Sie dann auch von den unterstützten Gestaltungsvorlagen abweichen. Wenn die benutzerdefinierte Gestaltungsvorlage nicht beibehalten wird, entgehen Ihrer Website die Updates und Verbesserungen, die Microsoft an den Gestaltungsvorlagen vornimmt.

Der obige Code weist die folgenden Abhängigkeiten an:

Die aktuelle Version von LinqJS enthält nicht die in den oben angegebenen Code verwendete ByHierarchy Methode und wird den Navigationsbereich Code unterbrechen. Um dieses Problem zu beheben, fügen Sie die folgende Methode zur Datei Linq.js vor der Zeile "Flatten:-Funktion ()".

ByHierarchy: function(firstLevel, connectBy, orderBy, ascending, parent) {
     ascending = ascending == undefined ? true : ascending;
     var orderMethod = ascending == true ? 'OrderBy' : 'OrderByDescending';
     var source = this;
     firstLevel = Utils.CreateLambda(firstLevel);
     connectBy = Utils.CreateLambda(connectBy);
     orderBy = Utils.CreateLambda(orderBy);
    
     //Initiate or increase level
     var level = parent === undefined ? 1 : parent.level + 1;

    return new Enumerable(function() {
         var enumerator;
         var index = 0;

        var createLevel = function() {
                 var obj = {
                     item: enumerator.Current(),
                     level : level
                 };
                 obj.children = Enumerable.From(source).ByHierarchy(firstLevel, connectBy, orderBy, ascending, obj);
                 if (orderBy !== undefined) {
                     obj.children = obj.children[orderMethod](function(d) {
                         return orderBy(d.item); //unwrap the actual item for sort to work
                     });
                 }
                 obj.children = obj.children.ToArray();
                 Enumerable.From(obj.children).ForEach(function(child) {
                     child.getParent = function() {
                         return obj;
                     };
                 });
                 return obj;
             };

        return new IEnumerator(

        function() {
             enumerator = source.GetEnumerator();
         }, function() {
             while (enumerator.MoveNext()) {
                 var returnArr;
                 if (!parent) {
                     if (firstLevel(enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }

                } else {
                     if (connectBy(parent.item, enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }
                 }
             }
             return false;
         }, function() {
             Utils.Dispose(enumerator);
         })
     });
 },

Hinweis : Haftungsausschluss für maschinelle Übersetzungen: Dieser Artikel wurde mithilfe eines Computersystems und ohne jegliche Bearbeitung durch Personen übersetzt. Microsoft bietet solche maschinellen Übersetzungen als Hilfestellung für Benutzer ohne Englischkenntnisse an, damit Sie von den Informationen zu Produkten, Diensten und Technologien von Microsoft profitieren können. Da es sich bei diesem Artikel um eine maschinelle Übersetzung handelt, enthält er möglicherweise Fehler in Bezug auf (Fach-)Terminologie, Syntax und/oder Grammatik.

Ihre Fähigkeiten erweitern
Schulung erkunden
Neue Funktionen als Erster erhalten
An Office Insider teilnehmen

War diese Information hilfreich?

Vielen Dank für Ihr Feedback!

Vielen Dank für Ihr Feedback. Es klingt, als ob es hilfreich sein könnte, Sie mit einem unserer Office-Supportmitarbeiter zu verbinden.

×