Tùy chọn dẫn hướng cho SharePoint Online

Quan trọng:  Bài viết này là dịch máy, hãy xem tuyên bố miễn trừ trách nhiệm. Bạn hãy tìm phiên bản tiếng Anh của bài viết này tại đây để tham khảo.

Bài viết này mô tả cách để cải thiện thời gian tải trang SharePoint Online bằng cách dùng dẫn hướng cấu trúc và điều chỉnh theo tìm kiếm dẫn hướng.

Dẫn hướng toàn cầu và các truy vấn yêu cầu để xây dựng dẫn hướng cấu trúc có thể làm cho trang của bạn, tải nhiều chậm trong SharePoint Online. Đây là vì mỗi các truy vấn sẽ gửi một yêu cầu cho SQL server. Đối với mỗi trang và site con mà bạn có, yêu cầu thêm được thực hiện đối với SQL server. Vấn đề này cũng ảnh hưởng đến các trang cái. Điều này có nghĩa là rằng dẫn hướng toàn cầu cũng bị ảnh hưởng.

Một số trang SharePoint yêu cầu cấu trúc phức tạp và lớn. Sử dụng phần dẫn hướng cấu trúc ra hộp, mà sử dụng nội dung theo truy vấn, có thể gây ra thời gian tải trang chậm do nhiều trang tầng. Mỗi của các trang con tầng cũng sẽ tạo ra một truy vấn khác.

Không có hai tùy chọn dẫn hướng ra hộp chính trong SharePoint cũng như thứ ba, phương pháp tùy chỉnh, điều chỉnh theo tìm kiếm. Mỗi tùy chọn có chuyên gia CNTT và nhược điểm như được nêu trong bảng sau đây.

Dẫn hướng cấu trúc

Dẫn hướng được quản lý

Điều chỉnh theo tìm kiếm dẫn hướng

Chuyên gia:

  • Dễ dàng để cấu hình

  • Cắt bảo mật

  • Tự động Cập Nhật khi site được thêm

Chuyên gia:

  • Dễ dàng để duy trì

Chuyên gia:

  • Cắt bảo mật

  • Tự động Cập Nhật khi site được thêm

  • Nhanh chóng tải thời gian và được đệm ẩn cục bộ dẫn hướng cấu trúc

Nhược điểm:

  • Có thể thực hiện kém với cấu trúc site phức tạp

Nhược điểm:

  • Không tự động Cập Nhật để phản ánh cấu trúc site

Nhược điểm:

  • Không có khả năng dễ dàng thứ tự trang

  • Yêu cầu tùy chỉnh trang chính (kỹ năng cần thiết)

Nếu bạn có trang với nhiều trang con và bạn đang dùng dẫn hướng cấu trúc, nó có thể làm chậm trang của bạn sẽ tải đáng kể. Tùy chọn phù hợp nhất cho trang của bạn sẽ phụ thuộc trên trang yêu cầu của bạn và trên khả năng kỹ thuật của bạn. Nếu bạn thấy thoải mái khi dùng một trang chính tùy chỉnh và có một số chức năng trong tổ chức để duy trì các thay đổi có thể xảy ra trong trang cái mặc định cho SharePoint Online, sau đó tùy chọn điều chỉnh theo tìm kiếm sẽ tạo ra trải nghiệm người dùng tốt nhất. Nếu bạn muốn một giữa đất đơn giản từ dẫn hướng cấu trúc ra trong hộp tìm kiếm, rồi dẫn hướng được quản lý là một tùy chọn tốt. Tùy chọn dẫn hướng được quản lý có thể được duy trì thông qua cấu hình, không liên quan đến mã tùy chỉnh tệp và đó là đáng kể nhanh hơn ra hộp dẫn hướng cấu trúc.

Phương pháp khác là cơ cấu lại trang web hiện có và giảm số lượng mục dẫn hướng và trang con bắt buộc. Đây là vì dẫn hướng cấu trúc thực hiện tốt miễn là cấu trúc site và dẫn hướng không phải là quá phức tạp.

Bài viết này so sánh các phương pháp khác nhau trong một tuyển tập trang ví dụ. Ví dụ tuyển tập trang có 11 site con và mỗi trang con có tối thiểu bốn trang con bổ sung.

Ảnh chụp màn hình cho thấy các site và site con

Dùng dẫn hướng cấu trúc trong SharePoint Online

Đây là phần dẫn hướng ra hộp sử dụng theo mặc định và giải pháp đơn giản và phù hợp nhất trong hầu hết các trường hợp. Trừ khi không có cấu trúc phức tạp của nhiều trang con hoặc nhiều cấp độ site con, dẫn hướng cấu trúc sẽ thực hiện tốt. Những lợi thế chính của phương pháp này là nó được cắt bảo mật, tự động Cập Nhật khi trang mới được thêm vào và không yêu cầu bất kỳ tùy chỉnh trang chính. Các người dùng có thể cũng dễ dàng thêm mục, ẩn các mục và quản lý dẫn hướng từ trang thiết đặt.

Bật dẫn hướng cấu trúc trong SharePoint Online

Để minh họa cách hiệu năng trong giải pháp SharePoint Online chuẩn với dẫn hướng cấu trúc và hiển thị subsites tùy chọn bật tính năng. Dưới đây một ảnh chụp màn hình thiết đặt được tìm thấy trên trang Thiết đặt trang > dẫn hướng.

Ảnh chụp màn hình hiển thị site con

Phân tích hiệu suất dẫn hướng cấu trúc trong SharePoint Online

Để phân tích hiệu suất của một trang SharePoint sử dụng tab mạng của công cụ nhà phát triển F12 trong Internet Explorer.

Ảnh chụp màn hình hiển thị tab Mạng của công cụ dành cho nhà phát triển F12

Trên tab mạng , bấm vào trang .aspx được đang được tải và sau đó bấm vào tab chi tiết .

Ảnh chụp màn hình hiển thị tab chi tiết

Bấm vào Tiêu đề phản hồi.

Ảnh chụp màn hình của tab Chi tiết

SharePoint trả về một số thông tin chẩn đoán hữu ích trong tiêu đề phản hồi của nó. Một trong các hữu ích nhất là SPRequestDuration    là giá trị, trong phần nghìn giây, của khoảng thời gian yêu cầu đã thực hiện để quy trình trên máy chủ.

Chụp Hiển thị site con màn hình sau đây được chọn cho dẫn hướng cấu trúc. Điều này có nghĩa là có chỉ nối kết tuyển tập site trong thanh dẫn hướng chung:

Ảnh chụp màn hình hiển thị thời gian tải dưới dạng thời gian yêu cầu

Phím SPRequestDuration    có một giá trị 245 mili giây. Điều này biểu thị thời gian mà nó đã thực hiện để trả về yêu cầu. Vì không có chỉ mục dẫn hướng trên trang web, đây là một tiêu chuẩn tốt cho cách SharePoint Online sẽ thực hiện không có lượng lớn dẫn hướng. Ảnh chụp màn hình kế tiếp Hiển thị cách thêm một trong các site con ảnh hưởng tới khóa này.

Ảnh chụp màn hình cho thấy thời gian yêu cầu là 2502 ms

Thêm các trang con có tăng đáng kể thời gian cần để trả về yêu cầu trang.

Lợi ích của việc sử dụng phần dẫn hướng có cấu trúc thông thường là bạn có thể dễ dàng sắp xếp thứ tự, ẩn các trang web, thêm trang, kết quả được cắt bảo mật, và bạn không deviating từ các trang cái được hỗ trợ được dùng trong SharePoint Online. Nếu bạn cấu trúc site của bạn cẩn thận và giảm thiểu số trang con trong tuyển tập trang của bạn rồi dẫn hướng cấu trúc sẽ thực hiện tốt.

Dùng dẫn hướng được quản lý và được quản lý siêu dữ liệu trong SharePoint Online

Dẫn hướng được quản lý là một tùy chọn xuất hộp khác mà bạn có thể dùng để tạo lại cùng một sắp xếp các chức năng dưới dạng dẫn hướng cấu trúc.

Lợi thế của việc sử dụng siêu dữ liệu được quản lý là nó nhanh hơn nhiều để truy xuất dữ liệu hơn bằng cách dùng nội dung bằng truy vấn để xây dựng dẫn hướng trang. Mặc dù đó là nhiều nhanh hơn có là không cách bảo mật trim kết quả vì vậy nếu người dùng không có quyền truy nhập vào site đã cho, nối kết sẽ vẫn hiển thị nhưng sẽ dẫn đến thông báo lỗi.

Làm thế nào để thực hiện việc dẫn hướng được quản lý và kết quả   

Có một số bài viết trên TechNet về các chi tiết của dẫn hướng được quản lý, ví dụ, hãy xem tổng quan về dẫn hướng được quản lý trong SharePoint Server 2013.

Để thực hiện việc dẫn hướng được quản lý, bạn cần phải có thời hạn lưu trữ các quyền quản trị. Bằng cách thiết lập các thuật ngữ với URL khớp với cấu trúc của tuyển tập trang, dẫn hướng được quản lý có thể dùng để dẫn hướng cấu trúc thay thế. Ví dụ:

Ảnh chụp màn hình của ví dụ về Site con 1

Ví dụ sau đây Hiển thị hiệu suất của dẫn hướng phức tạp bằng cách dùng dẫn hướng được quản lý.

Ảnh chụp màn hình của ví dụ về SPRequestDuration

Dùng dẫn hướng được quản lý nhất quán cải thiện hiệu suất so với nội dung bằng cách tiếp cận dẫn hướng cấu trúc của truy vấn.

Sử dụng điều chỉnh theo tìm kiếm phía máy khách tính năng tạo script

Dùng tìm kiếm, bạn có thể tận dụng các chỉ mục được dựng sẵn ở nền bằng cách dùng tìm kéo liên tục. Điều này có nghĩa là không có truy vấn Nội dung lượng lớn. Kết quả tìm kiếm được kéo từ chỉ mục tìm kiếm và kết quả được cắt bảo mật. Đây là nhanh hơn bằng cách dùng truy vấn Nội dung thông thường. Dùng tìm kiếm cho dẫn hướng cấu trúc, đặc biệt là nếu bạn có một cấu trúc site phức tạp, sẽ tăng tốc trang thời gian tải đáng kể. Lợi thế chính của này qua dẫn hướng được quản lý là bạn hưởng lợi từ xén bảo mật.

Phương pháp này bao gồm tạo trang chính tùy chỉnh và thay thế mã ra hộp dẫn hướng với HTML tùy chỉnh. Hãy làm theo quy trình này để thay thế mã dẫn hướng trong seattle.html tệp.

Trong ví dụ này, bạn sẽ mở tệp seattle.html và thay thế toàn bộ thành phần id = "DeltaTopNavigation" với mã HTML tùy chỉnh.

Ví dụ: Để thay thế mã ra hộp dẫn hướng trong trang cái

  1. Dẫn hướng đến Trang thiết đặt trang.

  2. Mở bộ sưu tập trang chính bằng cách bấm vào Trang chính.

  3. Từ đây, bạn có thể dẫn hướng qua thư viện và tải xuống tệp seattle.master.

  4. Sửa mã dùng một trình soạn thảo văn bản và xóa bỏ chặn mã trong chụp màn hình sau đây.

    Ảnh chụp màn hình của mã DeltaTopNavigation cần xóa
  5. Loại bỏ mã giữa các < SharePoint:AjaxDelta id = "DeltaTopNavigation" > và < \SharePoint:AjaxDelta > thẻ và thay thế bằng đoạn mã sau đây:

    <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. Thay thế URL trong tải hình ảnh neo thẻ đầu, với nối kết để tải một ảnh trong tuyển tập trang của bạn. Sau khi bạn đã thực hiện các thay đổi, đổi tên tệp và sau đó tải nó lên bộ sưu tập trang chính. Điều này tạo ra một tệp .master mới.

  7. HTML này là đánh dấu cơ bản sẽ được nhập cùng bằng kết quả tìm kiếm trả về từ mã JavaScript. Bạn sẽ cần phải sửa mã sau đây để thay đổi giá trị cho var root = “site collection URL như chứng minh trong đoạn mã sau đây:

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

    Tệp JavaScript toàn bộ là như sau:

    //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");
    

    Nói tóm lại mã Hiển thị ở trên trong hàm $(document).ready jQuery có một đối tượng viewModel được tạo và sau đó loadNavigationNodes() hoạt trên đối tượng đó được gọi là. Hàm này cũng sẽ tải cấu trúc phân cấp dẫn hướng xây dựng trước đó được lưu trữ trong kho lưu trữ cục bộ HTML5 trên trình duyệt máy khách, hoặc nó gọi hàm queryRemoteInterface().

    QueryRemoteInterface() xây dựng một yêu cầu sử dụng hàm getRequest() với truy vấn tham số được xác định trước trong kịch bản và sau đó trả về dữ liệu từ máy chủ. Dữ liệu này là thiết phải là một mảng của tất cả các trang trong tuyển tập trang được biểu thị dưới dạng đối tượng truyền dữ liệu với các thuộc tính khác nhau. Dữ liệu này được sửa phân tách rồi bằng dữ liệu gắn kết các giá trị vào HTML mà chúng tôi đã xác định phiên bản cũ hơn, vào đối tượng đã xác định trước đó SPO.Models.NavigationNode dùng Knockout.js để tạo các thuộc tính quan sát để sử dụng. Các đối tượng đó được đặt thành một mảng kết quả. Mảng này được phân tách thành JSON sử dụng loại trực tiếp và lưu trữ trong kho lưu trữ duyệt cục bộ cho nâng cao hiệu suất trên quá trình tải trang trong tương lai.

  8. Tiếp theo, kết quả được gán cho mảng self.nodes và một cấu trúc phân cấp được xây dựng ra khỏi các đối tượng bằng cách dùng linq.js giao kết xuất cho một mảng self.heirarchy. Mảng này có đối tượng được gắn kết HTML. Đây thực hiện trong hàm toggleView() bởi truyền đối tượng tự ko.applyBinding() hàm. Sau đó sẽ khiến mảng cấu trúc phân cấp để được gắn kết HTML sau đây:

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

    Cuối cùng, xử lý sự kiện cho mouseenter và mouseexit sẽ được thêm vào thanh dẫn hướng mức cao nhất để xử lý các site con menu thả xuống được thực hiện trong các hàm addEventsToElements() .

    Kết quả của dẫn hướng có thể nhìn thấy trong màn hình ảnh chụp dưới đây:

    Ảnh chụp màn hình của kết quả dẫn hướng

    Trong ví dụ của chúng tôi phức tạp dẫn hướng trang tươi tải mà không hiển thị lưu bộ đệm ẩn cục bộ thời gian dành cho máy chủ đã cắt từ dẫn hướng cấu trúc tiêu chuẩn để có kết quả tương tự như cách tiếp cận dẫn hướng được quản lý.

    Ảnh chụp màn hình của SPRequestDuration 301

    Một lớn lợi ích của phương pháp này là rằng bằng cách sử dụng dung lượng lưu trữ cục bộ HTML5, dẫn hướng được lưu trữ cục bộ cho người dùng lần sau khi họ tải trang.

Chúng tôi nhận được cải tiến hiệu suất chính sử dụng các tìm kiếm API cho dẫn hướng cấu trúc; Tuy nhiên, nó sẽ đưa một số chức năng kỹ thuật để thực hiện và tùy chỉnh các chức năng này. Thực hiện ví dụ, các site được sắp xếp thứ tự giống nhau dưới dạng dẫn hướng cấu trúc ra hộp; Thứ tự bảng chữ cái. Nếu bạn muốn đi chệch khỏi thứ tự này, nó sẽ phức tạp hơn để phát triển và duy trì. Ngoài ra, phương pháp này yêu cầu bạn phải đi chệch từ các trang cái được hỗ trợ. Nếu trang chính tùy chỉnh không được duy trì, trang web của bạn sẽ nhỡ trên Cập Nhật và cải thiện Microsoft ý với các trang cái.

Mã trên đây có phụ thuộc sau đây:

Phiên bản hiện tại của LinqJS không chứa các phương pháp ByHierarchy được dùng trong mã trên đây và sẽ ngắt mã dẫn hướng. Để sửa lỗi này, hãy thêm phương pháp sau đây Linq.js tệp trước khi dòng "phẳng: chức năng ()".

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

Ghi chú: Tuyên bố miễn trừ trách nhiệm Dịch Máy: Bài viết này do một hệ thống máy tính dịch mà không có sự can thiệp của con người. Microsoft cung cấp những bản dịch máy này để giúp người dùng không nói tiếng Anh hiểu nội dung về các sản phẩm, dịch vụ và công nghệ của Microsoft. Do bài viết này được dịch máy nên có thể có các lỗi về từ vựng, cú pháp hoặc ngữ pháp.

Phát triển các kỹ năng của bạn
Khám phá nội dung đào tạo
Sở hữu tính năng mới đầu tiên
Tham gia Người dùng nội bộ Office

Thông tin này có hữu ích không?

Cảm ơn phản hồi của bạn!

Cảm ơn bạn đã phản hồi! Để trợ giúp tốt hơn, có lẽ chúng tôi sẽ kết nối bạn với một trong những nhân viên hỗ trợ Office của chúng tôi.

×