Možnosti navigace pro SharePoint

Tento článek popisuje weby s možnostmi navigace s povoleným publikováním SharePointu na SharePointu. Volba a konfigurace navigace významně ovlivňuje výkon a škálovatelnost webů v SharePointu. Šablona webu publikování SharePointu by se měla používat jenom v případě potřeby pro centralizovaný portál a funkce publikování by měla být povolena pouze na konkrétních webech a pouze v případě potřeby, protože při nesprávném použití může mít vliv na výkon.

Poznámka

Pokud používáte moderní možnosti navigace SharePointu, jako je mega nabídka, kaskádová navigace nebo navigace v centru, tento článek se na váš web nevztahuje. Moderní architektury sharepointového webu využívají více plochou hierarchii webů a hvězdicový model. To umožňuje dosáhnout mnoha scénářů, které nevyžadují použití funkce publikování sharepointového serveru.

Přehled možností navigace

Konfigurace zprostředkovatele navigace může výrazně ovlivnit výkon celého webu a je třeba pečlivě zvážit výběr poskytovatele navigace a konfigurace, která se efektivně škáluje podle požadavků sharepointového webu. Existují dva předefinované zprostředkovatelé navigace a také vlastní implementace navigace.

První možnost , Strukturální navigace, je doporučená možnost navigace v SharePointu pro klasické sharepointové weby, pokud pro svůj web zapnete ukládání strukturované navigace do mezipaměti. Tento poskytovatel navigace zobrazí navigační položky pod aktuálním webem a volitelně aktuální web a jeho stejné položky. Poskytuje další funkce, jako je oříznutí zabezpečení a výčet struktury lokality. Pokud je ukládání do mezipaměti zakázané, bude to mít negativní vliv na výkon a škálovatelnost a může to podléhat omezování.

Druhá možnost, navigace spravovaná (metadata), představuje navigační položky pomocí sady termínů spravovaných metadat. Pokud není potřeba, doporučujeme zakázat oříznutí zabezpečení. Oříznutí zabezpečení je povoleno jako nastavení zabezpečení ve výchozím nastavení pro tohoto poskytovatele navigace; Mnoho webů ale nevyžaduje režii související se zabezpečením, protože navigační prvky jsou často konzistentní pro všechny uživatele webu. S doporučenou konfigurací pro zakázání oříznutí zabezpečení tento poskytovatel navigace nevyžaduje výčet struktury webu a je vysoce škálovatelný s přijatelným dopadem na výkon.

Kromě předem prováděných poskytovatelů navigace mnoho zákazníků úspěšně implementuje alternativní vlastní implementace navigace. Viz skriptování na straně klienta řízené Search v tomto článku.

Klady a zápory možností navigace na SharePointu

Následující tabulka shrnuje výhody a nevýhody jednotlivých možností.

Strukturovaná navigace Spravovaná navigace navigace řízená Search Vlastní zprostředkovatel navigace
Profesionály:

Snadná údržba
Zabezpečení je oříznuté.
Automatická aktualizace během 24 hodin při změně obsahu
Profesionály:

Snadná údržba
Profesionály:

Zabezpečení je oříznuté.
Automatické aktualizace při přidání webů
Rychlá doba načítání a struktura navigace v místní mezipaměti
Profesionály:

Širší výběr dostupných možností
Rychlé načítání při správném použití ukládání do mezipaměti
Mnoho možností dobře funguje s responzivním návrhem stránky
Nevýhody:

Vliv na výkon, pokud je ukládání do mezipaměti zakázané
Podléhá omezení
Nevýhody:

Neaktualizovalo se automaticky tak, aby odráželo strukturu webu.
Vliv na výkon, pokud je povolené oříznutí zabezpečení nebo když je složitá navigační struktura
Nevýhody:

Bez možnosti snadno objednávat weby
Vyžaduje přizpůsobení stránky předlohy (vyžadují se technické dovednosti).
Nevýhody:

Vyžaduje se vlastní vývoj.
Je potřeba externí zdroj dat nebo uložená mezipaměť, např. Azure.

Nejvhodnější možnost pro váš web závisí na požadavcích na web a na vašich technických schopnostech. Pokud chcete snadno konfigurovatelného poskytovatele navigace, který se automaticky aktualizuje při změně obsahu, je dobrou volbou strukturální navigace s povolenou ukládáním do mezipaměti .

Poznámka

Použití stejného principu jako moderní sharepointové weby zjednodušením celkové struktury webu na plošší, ne hierarchickou strukturu zlepšuje výkon a zjednodušuje přechod na moderní sharepointové weby. To znamená, že místo jediné kolekce webů se stovkami webů (podwebů) je lepším přístupem mít mnoho kolekcí webů s velmi malým počtem podřízených webů (podřízených webů).

Analýza výkonu navigace v SharePointu

Nástroj Diagnostika stránek pro SharePoint je rozšíření prohlížeče pro prohlížeče Microsoft Edge a Chrome, které analyzuje moderní portál SharePointu i klasické stránky webu publikování. Tento nástroj funguje jenom pro SharePoint a nedá se použít na stránce systému SharePointu.

Nástroj vygeneruje sestavu pro každou analyzovanou stránku zobrazující výkon stránky s předdefinovanou sadou pravidel a zobrazí podrobné informace, když výsledky testu spadají mimo hodnotu směrného plánu. Správci a návrháři SharePointu můžou pomocí nástroje řešit problémy s výkonem a zajistit, aby byly nové stránky před publikováním optimalizované.

SPRequestDuration je zejména doba potřebná službě SharePoint ke zpracování stránky. Náročná navigace (například zahrnutí stránek do navigace), složité hierarchie webů a další možnosti konfigurace a topologie můžou výrazně přispět k delší době trvání.

Použití strukturované navigace v SharePointu

Toto je výchozí navigace, která se používá ve výchozím nastavení a je nejjednodušším řešením. Nevyžaduje žádné přizpůsobení a netechnický uživatel může také snadno přidávat položky, skrývat položky a spravovat navigaci ze stránky nastavení. Doporučujeme povolit ukládání do mezipaměti, jinak by došlo k nákladnému kompromisu výkonu.

Jak implementovat ukládání do mezipaměti strukturální navigace

V části Vzhleda chování>navigace v nastavení> webu můžete ověřit, jestli je pro globální nebo aktuální navigaci vybraná strukturovaná navigace. Výběr možnosti Zobrazit stránky bude mít negativní dopad na výkon.

Strukturovaná navigace s vybranou možností Zobrazit podřízené weby

Ukládání do mezipaměti je možné povolit nebo zakázat na úrovni kolekce webů a na úrovni webu a ve výchozím nastavení je povolené pro obě. Pokud chcete funkci povolit na úrovni kolekce webů, zaškrtněte v části Nastavení> webuNavigace v kolekci webů správa>kolekce webů políčko Povolit ukládání do mezipaměti.

Povolte ukládání do mezipaměti na úrovni kolekce webů.

Pokud chcete funkci povolit na úrovni webu, zaškrtněte v částiNavigacev nastavení> webu políčko Povolit ukládání do mezipaměti.

Povolte ukládání do mezipaměti na úrovni webu.

Použití spravované navigace a metadat v SharePointu

Spravovaná navigace je další předefinovaná možnost, kterou můžete použít k opětovnému vytvoření většiny stejných funkcí jako strukturální navigace. Spravovaná metadata je možné nakonfigurovat tak, aby měla povolené nebo zakázané oříznutí zabezpečení. Při konfiguraci se zakázaným oříznutím zabezpečení je spravovaná navigace poměrně efektivní, protože načítá všechny navigační odkazy s konstantním počtem volání serveru. Povolením oříznutí zabezpečení se však některé výhody výkonu spravované navigace negují.

Pokud potřebujete povolit oříznutí zabezpečení, doporučujeme:

  • Aktualizovat všechny odkazy popisné adresy URL na jednoduché odkazy
  • Přidání požadovaných uzlů pro oříznutí zabezpečení jako popisných adres URL
  • Omezit počet navigačních položek na maximálně 100 a maximálně tři úrovně hloubky

Mnoho webů nevyžaduje oříznutí zabezpečení, protože navigační struktura je často konzistentní pro všechny uživatele webu. Pokud je oříznutí zabezpečení zakázané a do navigace se přidá odkaz, ke kterému nemají přístup všichni uživatelé, odkaz se bude i nadále zobrazovat, ale bude mít za následek zprávu o odepření přístupu. Nehrozí riziko neúmyslného přístupu k obsahu.

Jak implementovat spravovanou navigaci a výsledky

Na webu Microsoft Learn je několik článků o podrobnostech spravované navigace. Podívejte se například na přehled spravované navigace na SharePoint Serveru.

Pokud chcete implementovat spravovanou navigaci, nastavte termíny s adresami URL odpovídajícími navigační struktuře webu. Spravovaná navigace se dá v mnoha případech dokonce ručně uspořádat, aby nahradila strukturální navigaci. Příklady:

Struktura webu služby SharePoint.)

Použití skriptování na straně klienta řízeného Search

Jedna běžná třída vlastních navigačních implementací zahrnuje vzory návrhu vykreslené klientem, které ukládají místní mezipaměť navigačních uzlů.

Tito poskytovatelé navigace mají několik klíčových výhod:

  • Obecně dobře fungují s responzivními návrhy stránek.
  • Jsou extrémně škálovatelné a výkonné, protože můžou vykreslovat bez nákladů na prostředky (a po vypršení časového limitu se aktualizovat na pozadí).
  • Tito poskytovatelé navigace můžou načítat navigační data pomocí různých strategií, od jednoduchých statických konfigurací až po různé dynamické zprostředkovatele dat.

Příkladem poskytovatele dat je použití navigace řízené Search, která umožňuje flexibilitu pro vytváření výčtů navigačních uzlů a efektivní zpracování oříznutí zabezpečení.

Existují i další oblíbené možnosti, jak vytvořit vlastní zprostředkovatele navigace. Další pokyny k vytvoření vlastního poskytovatele navigace najdete v tématu Řešení navigace pro portály SharePointu .

Pomocí vyhledávání můžete využít indexy vytvořené na pozadí pomocí průběžného procházení. Výsledky hledání se načítají z indexu vyhledávání a výsledky jsou oříznuté zabezpečením. To je obecně rychlejší než poskytovatelé navigace, kteří jsou součástí balení, když je vyžadováno oříznutí zabezpečení. Použití vyhledávání pro strukturní navigaci, zejména pokud máte složitou strukturu webu, výrazně zrychlí načítání stránek. Hlavní výhodou této možnosti oproti spravované navigaci je to, že využíváte ořezávání zabezpečení.

Tento přístup zahrnuje vytvoření vlastní stránky předlohy a nahrazení kódu předsefinované navigace vlastním kódem HTML. Postupujte podle tohoto postupu popsaného v následujícím příkladu a nahraďte navigační kód v souboru seattle.html. V tomto příkladu seattle.html otevřete soubor a nahradíte celý element id="DeltaTopNavigation" vlastním kódem HTML.

Příklad: Nahrazení předsefinované navigační kód na stránce předlohy

  1. Přejděte na stránku Nastavení webu.
  2. Otevřete galerii stránek předlohy kliknutím na Stránky předlohy.
  3. Odtud můžete procházet knihovnu a stáhnout soubor seattle.master.
  4. Upravte kód pomocí textového editoru a odstraňte blok kódu na následujícím snímku obrazovky.
    Odstraňte zobrazený blok kódu.
  5. Odeberte kód mezi značkami <SharePoint:AjaxDelta id="DeltaTopNavigation"> a <\SharePoint:AjaxDelta> a nahraďte ho následujícím fragmentem kódu:
<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 level1">
                <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 }">

                 <!-- ko if: children.length > 0-->
                    <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
                        <span class="menu-item-text" data-bind="text: item.Title">
                        </span>
                    </span>
                <!-- /ko -->
                <!-- ko if: children.length == 0-->
                    <span aria-haspopup="true" class="ms-navedit-flyoutArrow dynamic-children">
                        <span class="menu-item-text" data-bind="text: item.Title">
                        </span>
                    </span>
                <!-- /ko -->
                </a>

                <!-- ko if: children.length > 0-->
                <ul id="menu"  data-bind="foreach: children;" class="dynamic  level2" >
                    <li class="dynamic level2">
                        <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline  ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">

          <!-- ko if: children.length > 0-->
          <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
           <span class="menu-item-text" data-bind="text: item.Title">
           </span>
          </span>
           <!-- /ko -->
          <!-- ko if: children.length == 0-->
          <span aria-haspopup="true" class="ms-navedit-flyoutArrow dynamic-children">
           <span class="menu-item-text" data-bind="text: item.Title">
           </span>
          </span>
          <!-- /ko -->
                        </a>
          <!-- ko if: children.length > 0-->
         <ul id="menu" data-bind="foreach: children;" class="dynamic level3" >
          <li class="dynamic level3">
           <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>
           <!-- /ko -->
                    </li>
                </ul>
                <!-- /ko -->
            </li>
        </ul>
    </div>
</div>

6. Na začátku nahraďte adresu URL ve značce ukotvení načítání obrázku odkazem na načítání obrázku v kolekci webů. Po provedení změn přejmenujte soubor a nahrajte ho do galerie stránek předlohy. Tím se vygeneruje nový soubor .master.
7. Tento KÓD HTML je základní kód, který bude naplněn výsledky hledání vrácenými z kódu JavaScriptu. Budete muset upravit kód, abyste změnili hodnotu var root = "adresa URL kolekce webů", jak je znázorněno v následujícím fragmentu kódu:
var root = "https://spperformance.sharepoint.com/sites/NavigationBySearch";

8. Výsledky jsou přiřazeny k poli self.nodes a hierarchie je sestavena z objektů pomocí linq.js přiřazení výstupu k poli self.hierarchy. Toto pole je objekt, který je vázán na html. To se provádí ve funkci toggleView() předáním objektu self funkci ko.applyBinding().
To pak způsobí, že pole hierarchie bude vázáno na následující kód HTML:
<div data-bind="foreach: hierarchy" class="noindex ms-core-listMenu-horizontalBox">

Obslužné rutiny událostí pro mouseenter a mouseexit jsou přidány do navigace nejvyšší úrovně, aby se zpracovávaly rozevírací nabídky podřízeného addEventsToElements() webu, které se provádí ve funkci.

V našem příkladu složité navigace ukazuje načtení nové stránky bez místního ukládání do mezipaměti čas strávený na serveru, který byl zkrácen od srovnávací strukturální navigace, aby se dosáhlo podobného výsledku jako přístup ke spravované navigaci.

O souboru JavaScriptu...

Poznámka

Pokud používáte vlastní JavaScript, ujistěte se, že je povolená veřejná síť CDN a že je soubor v umístění CDN.

Celý soubor JavaScriptu je následující:

//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 firefox
    // 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.level1").mouseover(function () {
          var position = $(this).position();
          $(this).find("ul.level2").css({ width: 100, left: position.left + 10, top: 50 });
      })
   .mouseout(function () {
     $(this).find("ul.level2").css({  left: -99999, top: 0 });
   
    });
   
     $("li.level2").mouseover(function () {
          var position = $(this).position();
          console.log(JSON.stringify(position));
          $(this).find("ul.level3").css({ width: 100, left: position.left + 95, top:  position.top});
      })
   .mouseout(function () {
     $(this).find("ul.level3").css({  left: -99999, top: 0 });
    });
} _spBodyOnLoadFunctionNames.push("InitCustomNav");

Pokud chcete shrnout výše uvedený kód ve jQuery $(document).ready funkci, viewModel object je vytvořený objekt a pak loadNavigationNodes() se volá funkce pro daný objekt. Tato funkce buď načte dříve sestavenou navigační hierarchii uloženou v místním úložišti HTML5 klientského prohlížeče, nebo volá funkci queryRemoteInterface().

QueryRemoteInterface() Sestaví požadavek pomocí getRequest() funkce s parametrem dotazu definovaným dříve ve skriptu a pak vrátí data ze serveru. Tato data jsou v podstatě pole všech webů v kolekci webů reprezentované jako objekty přenosu dat s různými vlastnostmi.

Tato data se pak analyzují do dříve definovaných SPO.Models.NavigationNode objektů, které slouží Knockout.js k vytvoření pozorovatelných vlastností pro použití daty svázání hodnot do kódu HTML, který jsme definovali dříve.

Objekty jsou pak vloženy do pole výsledků. Toto pole se parsuje do formátu JSON pomocí knockoutu a ukládá se v místním úložišti prohlížeče, aby se zlepšil výkon při budoucím načítání stránek.

Výhody tohoto přístupu

Jednou z hlavních výhod tohoto přístupu je to, že při použití místního úložiště HTML5 se navigace uloží místně pro uživatele při příštím načtení stránky. Díky použití rozhraní API pro vyhledávání pro strukturovaná navigace jsme získali významná vylepšení výkonu. k provedení a přizpůsobení této funkce však vyžaduje určité technické schopnosti.

V ukázkové implementaci jsou lokality seřazeny stejným způsobem jako předem vychytávkovaná strukturní navigace; abecední pořadí. Pokud byste se chtěli od tohoto pořadí odchýlit, bylo by složitější vyvíjet a udržovat. Tento přístup také vyžaduje, abyste se odchýlili od podporovaných stránek předlohy. Pokud se vlastní stránka předlohy neudrží, váš web přijde o aktualizace a vylepšení, které Microsoft na stránkách předlohy provádí.

Výše uvedený kód má následující závislosti:

Aktuální verze LinqJS neobsahuje metodu ByHierarchy použitou ve výše uvedeném kódu a přeruší navigační kód. Chcete-li tento problém vyřešit, přidejte následující metodu do souboru Linq.js před řádek Flatten: function ().

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);
         })
     });
 },

Přehled spravované navigace na SharePoint Serveru

Strukturální ukládání do mezipaměti a výkon navigace