SharePoint Online에 대 한 탐색 옵션

이 문서에서는 관리 탐색 또는 검색 기반 탐색을 사용 하 여 SharePoint online 페이지 로드 시간 개선 하는 방법에 설명 합니다.

참고:  사용자 언어로 가능한 한 빨리 가장 최신의 도움말 콘텐츠를 제공하고자 합니다. 이 페이지는 자동화를 통해 번역되었으며 문법 오류나 부정확한 설명을 포함할 수 있습니다. 이 목적은 콘텐츠가 사용자에게 유용하다는 것입니다. 이 페이지 하단의 정보가 도움이 되었다면 알려주세요. 쉽게 참조할 수 있는 영어 문서 가 여기 있습니다.

전역 탐색 및 탐색 구조를 만드는 데 필요한 쿼리 로드 더 많은 천천히에서 SharePoint Online 페이지를 만들 수 있습니다. SQL server에 다른 요청을 보내는 각이 쿼리 때문입니다. 각 사이트와 사용 하는 하위 사이트에 대 한 더 많은 요청 SQL server에 적용 됩니다. 이 문제는 마스터 페이지를도 영향을 줍니다. 전역 탐색도 저하 되어 것입니다.

일부 SharePoint 사이트 크고 복잡 한 구조 필요 합니다. 콘텐츠 쿼리를 사용 하는 중 상자 구조 탐색을 사용 하 여 느린 페이지 로드 시간 여러 사이트 계층으로 인해 발생할 수 있습니다. 또한 각 하위 사이트 계층의 다른 쿼리를 만듭니다.

SharePoint 뿐만 아니라 세 가지, 사용자 지정 검색 기반 방식으로 기본 상자 탐색 옵션 두 가지가 있습니다. 각 옵션에는 장단점이 다음 표에 요약 된 대로 합니다.

탐색 구조

관리 되는 탐색

검색 기반 탐색

전문가:

  • 쉽게 구성할 수

  • 보안 트리밍

  • 사이트를 추가할 때 자동으로 업데이트

전문가:

  • 유지 관리 하기 쉬운

전문가:

  • 보안 트리밍

  • 사이트를 추가할 때 자동으로 업데이트

  • 로드 시간 및 로컬 캐시 된 탐색 구조 개요

단점:

  • 복잡 한 사이트 구조와 성능이 저하

단점:

  • 사이트 구조를 반영 하도록 자동으로 업데이트

단점:

  • 쉽게 순서 사이트에 기능이 없습니다

  • 사용자 지정 하는 마스터 페이지 (데 필요한 기술) 필요

많은 하위 사이트가 포함 된 사이트 및 탐색 구조를 사용 하는, 저하 될 수 있음 페이지 로드 크게 합니다. 사이트에 대 한 가장 적합 한 옵션은 기술 기능 및 사이트 요구 사항에 따라 달라 집니다. 사용자 지정 마스터 페이지 사용에 익숙한 경우 몇 가지 기능이 SharePoint Online에 대 한 기본 마스터 페이지에 발생할 수 있는 변경 내용을 유지 하는 조직 내에서 검색 기반 옵션 최상의 사용자 환경을 생성 됩니다. 기본 구조 탐색 및 검색 간에 간단한 중간 지점을 원한다 면 관리 탐색 매우 유용한 옵션입니다. 관리 되는 탐색 옵션을 통해 유지 관리할 수 있습니다 구성, 코드 사용자 지정 파일을 포함 하지 않는 한 탐색 구조의 상자 보다 훨씬 빠릅니다.

또 다른 방법은 기존 사이트 구조 탐색 항목 및 필수 하위 사이트의 수를 줄입니다. 탐색 구조 잘 만큼 얼마 사이트 구조 및 탐색이 너무 복잡 한 수행 하기 때문입니다.

이 문서의 예제에서는 사이트 모음에 다양 한 방법 비교합니다. 예제에서는 사이트 모음 11 하위 사이트가 있고 각 하위 사이트에 4 개 이상 추가 하위 사이트입니다.

사이트 및 하위 사이트를 보여 주는 스크린샷

SharePoint Online에서 탐색 구조를 사용 하 여

기본적으로 사용 되는 상자 탐색 이며 대부분의 경우에서 가장 간단 하 고 적절 한 솔루션입니다. 여러 하위 사이트 또는 여러 수준의 하위 사이트가 복잡 한 구조 아닌 경우 탐색 구조 잘 수행 합니다. 이 방법의 주요 이점 하 보안 트리밍, 새 사이트 추가 될 때 자동으로 업데이트 되 고 모든 사용자 지정 마스터 페이지의 필요 하지 않습니다. 됩니다. 기술적 사용자가도 쉽게 항목을 추가, 항목을 숨기려면 하 고 탐색 설정 페이지에서 관리 합니다.

SharePoint Online에서 탐색 구조 켜기

탐색 구조 및 표시와 표준 SharePoint Online 솔루션의 성능 옵션 하위 방법을 보여 주기 위해 설정 됩니다. 다음 화면으로 촬영 사이트 설정 페이지에 있는 설정 > 탐색 합니다.

하위 사이트를 나타내는 스크린샷

SharePoint Online에서 탐색 구조 성능 분석

분석을 위한 SharePoint 페이지의 성능을 Internet Explorer에서 F12 개발자 도구 네트워크 탭을 사용 합니다.

F12 개발 도구 네트워크 탭을 나타내는 스크린샷

네트워크 탭에서 로드 되 고.aspx 페이지에서 클릭 한 다음 세부 정보 탭을 클릭 합니다.

세부 정보 탭을 나타내는 스크린샷

응답 헤더를 클릭합니다.

세부 정보 탭 스크린샷

SharePoint의 응답 헤더의 몇 가지 유용한 진단 정보를 반환합니다. 가장 유용 중 하나는 값 (밀리초) 얼마나 요청 하는 데 걸린 서버에서 프로세스의 SPRequestDuration    입니다.

다음 화면에 표시 하위 사이트를 탐색 구조에 대 한 체크 인 아닙니다. 전역 탐색 모음에서 사이트 모음 링크는 것을 나타냅니다.

요청 기간만큼의 로드 시간을 보여 주는 스크린샷

SPRequestDuration    키에 245 밀리초 값입니다. 요청을 반환 하는 데 걸린 시간을 나타냅니다. 사이트의 탐색 항목을 하나만 이므로 용 SharePoint Online 수행 하는 방법을 중형 탐색 없이 좋은 벤치 마크입니다. 다음 스크린샷은 추가 하는 하위 사이트에서이 키 미치는 영향을 보여 줍니다.

2502ms의 요청 기간을 나타내는 스크린샷

하위 사이트 추가 페이지 요청을 반환 하는 데 걸리는 시간 크게 증가 합니다.

일반 구조적된 탐색 사용의 이점은 하면 수 쉽게 순서에 따라 구성, 사이트 숨기기, 되 페이지 추가, 결과 보안 트리밍 SharePoint Online에서 사용 되는 지원 되는 마스터 페이지에서 벗어난 하지는 합니다. 사이트를 신중 하 게 구성 및 하위 사이트의 사이트 모음에서 최소화 하는 경우 다음 탐색 구조 잘 수행 합니다.

SharePoint Online에서 관리 탐색 및 관리 되는 메타 데이터 사용

관리 되는 탐색 탐색 구조와 기능을 동일한 종류를 다시 만드는 데 사용할 수 있는 다른 상자 옵션입니다.

관리 되는 메타 데이터를 사용할 때의 이점은 쿼리에 의해 콘텐츠를 사용 하 여 사이트 탐색을 보다 데이터를 검색 하려면 훨씬 더 빠른 것입니다. 훨씬 더 빠르게 방법이 있으면 보안 trim 결과 것은 아니지만 하므로 사용자 지정된 사이트에 액세스할 수 없는 경우 링크 것 계속 표시 되지만 오류 메시지에 연결 됨.

관리 되는 탐색 하 고 결과 구현 하는 방법   

여러 문서에는 TechNet 관리 탐색의 세부 정보에 대 한 예를 들어 SharePoint Server 2013에서 관리 되는 탐색의 개요를 참고 하세요.

관리 탐색을 구현 하기 위해 용어 저장소 관리자 권한이 있는 해야 합니다. Url이 사이트 모음의 구조와 일치 하는 용어를 설정 하 여 관리 탐색 대체 탐색 구조를 사용할 수 있습니다. 예를 들어:

하위 사이트1 예제 스크린샷

다음 예제에서는 관리 탐색을 사용 하 여 복잡 한 탐색의 성능을 보여 줍니다.

SPRequestDuration 예제 스크린샷

지속적으로 관리 탐색을 사용 하 여 쿼리 탐색 구조 방법을 사용 하 여 콘텐츠에 비해 성능이 향상 됩니다.

검색 기반 클라이언트 쪽 스크립트를 사용 하 여

검색을 사용 하 여 연속 크롤링을 사용 하 여 백그라운드에서 구축 된 인덱스를 활용할 수 있습니다. 중형 콘텐츠 쿼리가 없는 것입니다. 검색 인덱스에서 검색 결과 가져오는 한 결과 보안 트리밍 합니다. 일반 콘텐츠 쿼리를 사용 하 여 보다 빠릅니다. 탐색 구조에 대 한 검색을 사용 하 여 복잡 한 사이트 구조를 사용 중인 경우에 특히 더 빠르게 처리할 페이지 로드 시간 상당히 합니다. 주 이러한 관리 탐색을 통해 장점이 보안 조정에서 이점이 있습니다.

이 방법은 사용자 지정 마스터 페이지를 만들고 사용자 지정 html의 상자 탐색 코드를 대체 합니다. 파일 seattle.html의 탐색 코드 대체 하려면이 절차를 따릅니다.

이 예제에서는 seattle.html 파일 열기 및 전체 요소 바꿀가 id "DeltaTopNavigation" = 사용자 지정 HTML 코드를 사용 합니다.

예: 마스터 페이지의 상자에서 탐색 코드를 바꾸려면

  1. 사이트 설정 페이지로 이동 합니다.

  2. 마스터 페이지 를 클릭 하 여 마스터 페이지 갤러리를 엽니다.

  3. 여기에서 라이브러리를 탐색할 수 있으며 seattle.master 파일 다운로드할 수 있습니다.

  4. 텍스트 편집기를 사용 하 여 코드를 편집 하 고 다음 화면에서 코드 블록을 삭제 합니다.

    삭제할 DeltaTopNavigation 코드 스크린샷
  5. 사이의 코드 제거는 < SharePoint:AjaxDelta id "DeltaTopNavigation" = > 및 < \SharePoint:AjaxDelta > 태그를 지정 하 고 다음 코드 조각으로 대체:

    <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. URL을 로드 하는 대체 사이트 모음에서 로딩 이미지에 대 한 링크와 시작 부분에 앵커 태그 이미지입니다. 변경 내용을 변경한 후 파일 이름을 바꾼 후 마스터 페이지 갤러리에 업로드 합니다. 새.master 파일을 생성합니다.

  7. 이 HTML JavaScript 코드에서 반환 되는 검색 결과에서 채울 수 있는 기본 태그입니다. 다음 코드 조각에서와 같이 var root = “site collection URL 에 대 한 값을 변경 하려면 다음 코드를 편집 해야 합니다.

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

    전체 JavaScript 파일은 다음과 같습니다.

    //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.level1").mouseover(function () {
              var 위치 = $(this).position();
              (이) $.find("ul.level2").css ({너비: 100, 왼쪽: position.left + 10, top: 50}).

    })
       .mouseout(function () {
         (이) $.find("ul.level2").css ({왼쪽: 위쪽-99999: 0}).

        });

         $("li.level2").mouseover(function () {
              var 위치 = $(this).position();
              console.log(JSON.stringify(position));
              (이) $.find("ul.level3").css ({너비: 100, 왼쪽: position.left + 95, top: position.top}).        

    })
       .mouseout(function () {
         (이) $.find("ul.level3").css ({왼쪽: 위쪽-99999: 0}).
        });

    } _spBodyOnLoadFunctionNames.push("InitCustomNav");

    생성 된 viewModel 개체 작업과 loadNavigationNodes() 해당 개체에서 작동 하는 다음 jQuery $(document).ready 함수에서 위의 코드를 요약 하면 이라고 합니다. 이 함수는 클라이언트 브라우저의 HTML5 로컬 저장소에 저장 된 이전에 작성 된 탐색 계층 구조 하거나 로드 하거나 queryRemoteInterface()함수 호출 합니다.

    QueryRemoteInterface()getRequest() 함수를 사용 하 여 스크립트의 앞부분에서 정의 된 쿼리 매개 변수를 사용 하 여 요청을 작성 하 고 서버에서 데이터를 반환 합니다. 이 데이터는 다양 한 속성을 가진 데이터 전송 개체로 표현 사이트 모음의 모든 사이트의 기본적으로 배열 합니다. 이 데이터 데이터 값 앞에서 정의한 HTML에 바인딩 하 여 Knockout.js를 사용 하 여 사용에 대 한 눈에 띄는 속성을 만들 수 있는 이전에 정의 된 SPO.Models.NavigationNode 개체로 구문 분석 한 다음 됩니다. 그런 다음 개체는 결과 배열에 배치 됩니다. 이 배열의 녹아웃을 사용 하 여 JSON으로 구문 분석 되 고 이후 페이지 로드의 성능 향상 시키기 위해 로컬 브라우저 저장소에 저장 됩니다.

  8. 다음으로, 결과 self.nodes 배열에 할당 된 및 계층 구조 linq.js 출력 배열 self.heirarchy에 할당을 사용 하 여 개체 아웃 만들어집니다. 이 배열의 HTML에 바인딩된 개체입니다. 이 자체 개체 ko.applyBinding() 함수에 전달 하 여 toggleView() 함수에 수행 됩니다. 다음 다음 HTML에 바인딩되어 계층 구조 배열 실행 되도록 합니다.

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

    마지막으로, mouseenter 및 mouseexit 에 대 한 이벤트 처리기 addEventsToElements() 함수에서 수행 된 하위 사이트 드롭다운 메뉴를 처리 하도록 최상위 탐색에 추가 됩니다.

    화면 아래에서 탐색의 결과 볼 수 있습니다.

    탐색 결과 스크린샷

    복잡 한 탐색이 예제에서는 새로운 페이지 로컬 캐시에서 볼 수 있는 서버에 소요 된 시간 없이 로드에는 관리 탐색 방법으로 비슷한 결과 얻기 위해 탐색 구조 벤치 마크에서에서 잘라내기 되었습니다.

    SPRequestDuration 301 스크린샷

    이 방법은의 주요 이점 중 하나는 HTML5 로컬 저장소를 사용 하 여 탐색 로컬에 저장 되어 사용자 다음에 페이지를 로드할 때입니다.

검색 API를 사용 하 여 탐색 구조;에 대 한 주요 성능 향상을 얻게 그러나 거치면 몇 가지 기술 기능을 실행 하 고이 기능을 사용자 지정할 수 있습니다. 예제 구현에서 사이트의 기본 구조 탐색;와 같은 방식으로 정렬 사전 순으로 정렬 합니다. 이 순서에서 벗어날 하려는 경우 개발 하 고 관리 더 복잡 한 것입니다. 또한이 방법을 사용 하려면 지원 되는 마스터 페이지에서 벗어날 합니다. 사용자 지정 마스터 페이지 유지 되지 않는 경우 사이트 됩니다 놓칠을 업데이트 하 고 Microsoft가 마스터 페이지를 개선 합니다.

위의 코드에는 다음과 같은 의존 관계가 있으면 됩니다.

LinqJS의 현재 버전 위의 코드에 사용 되는 ByHierarchy 메서드를 포함 하지 않는 한 탐색 코드의 연결이 끊어집니다. 이 문제를 해결 하려면 다음 방법을 줄 앞 Linq.js 파일에 추가 "결합: () 함수"입니다.

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);
         })
     });
 },
Office 기술 확장
교육 살펴보기
새로운 기능 우선 가져오기
Office Insider 참여

이 정보가 유용한가요?

의견 주셔서 감사합니다!

피드백을 주셔서 감사합니다. Office 지원 에이전트와 연락하는 것이 도움이 될 것 같습니다.

×