Udostępnij za pośrednictwem


Samouczek: dodawanie stronicowania do wyników wyszukiwania przy użyciu zestawu .NET SDK

Dowiedz się, jak zaimplementować dwa różne systemy stronicowania, pierwszy na podstawie numerów stron i drugi na nieskończonym przewijaniu. Oba systemy stronicowania są powszechnie używane, a wybranie odpowiedniego zależy od środowiska użytkownika, które chcesz z wynikami.

Ten samouczek zawiera informacje na temat wykonywania następujących czynności:

  • Rozszerzanie aplikacji przy użyciu stronicowania numerowanego
  • Rozszerzanie aplikacji przy użyciu nieskończonego przewijania

Omówienie

Ten samouczek nakłada system stronicowania na wcześniej utworzony projekt opisany w samouczku Tworzenie pierwszej aplikacji wyszukiwania .

Ukończone wersje kodu opracowywanego w tym samouczku można znaleźć w następujących projektach:

Wymagania wstępne

Rozszerzanie aplikacji przy użyciu stronicowania numerowanego

Numerowane stronicowanie to wybrany system stronicowania dla głównych komercyjnych wyszukiwarek internetowych i wielu innych witryn internetowych wyszukiwania. Stronicowanie numerowane zwykle zawiera opcję "next" i "previous" oprócz zakresu rzeczywistych numerów stron. Dostępna może być również opcja "pierwsza strona" i "ostatnia strona". Te opcje z pewnością zapewniają użytkownikowi kontrolę nad nawigowaniem po wynikach opartych na stronach.

W tym samouczku dodasz system zawierający pierwsze, poprzednie, następne i ostatnie opcje wraz z numerami stron, które nie zaczynają się od 1, ale zamiast tego otaczają bieżącą stronę, na której znajduje się użytkownik (na przykład jeśli użytkownik patrzy na stronę 10, być może numery stron 8, 9, 10, 11 i 12).

System będzie wystarczająco elastyczny, aby umożliwić ustawienie liczby widocznych numerów stron w zmiennej globalnej.

System traktuje przyciski numerów stron po lewej i prawej stronie jako specjalne, co oznacza, że wyzwolą zmianę zakresu wyświetlanych numerów stron. Jeśli na przykład są wyświetlane numery stron 8, 9, 10, 11 i 12, a użytkownik kliknie 8, zakres numerów stron zmieni się na 6, 7, 8, 9 i 10. I jest podobna zmiana w prawo, jeśli wybrali 12.

Dodawanie pól stronicowania do modelu

Otwórz podstawowe rozwiązanie strony wyszukiwania.

  1. Otwórz plik modelu SearchData.cs.

  2. Dodaj zmienne globalne, aby obsługiwać stronicowanie. W usłudze MVC zmienne globalne są deklarowane we własnej klasie statycznej. WynikiPerPage ustawia liczbę wyników na stronę. MaxPageRange określa liczbę widocznych numerów stron w widoku. PageRangeDelta określa, ile stron powinno zostać przesuniętych w lewo lub w prawo, po wybraniu lewej lub prawej większości numerów stron. Zazwyczaj ta ostatnia liczba wynosi około połowy elementu MaxPageRange. Dodaj następujący kod do przestrzeni nazw.

    public static class GlobalVariables
    {
        public static int ResultsPerPage
        {
            get
            {
                return 3;
            }
        }
        public static int MaxPageRange
        {
            get
            {
                return 5;
            }
        }
    
        public static int PageRangeDelta
        {
            get
            {
                return 2;
            }
        }
    }
    

    Porada

    Jeśli uruchamiasz ten projekt na urządzeniu z mniejszym ekranem, takim jak laptop, rozważ zmianę elementu ResultsPerPage na 2.

  3. Dodaj właściwości stronicowania do klasy SearchData po właściwości searchText .

    // The current page being displayed.
    public int currentPage { get; set; }
    
    // The total number of pages of results.
    public int pageCount { get; set; }
    
    // The left-most page number to display.
    public int leftMostPage { get; set; }
    
    // The number of page numbers to display - which can be less than MaxPageRange towards the end of the results.
    public int pageRange { get; set; }
    
    // Used when page numbers, or next or prev buttons, have been selected.
    public string paging { get; set; }
    

Dodawanie tabeli opcji stronicowania do widoku

  1. Otwórz plik index.cshtml i dodaj następujący kod bezpośrednio przed zamknięciem </body> tag. Ten nowy kod przedstawia tabelę opcji stronicowania: pierwsza, poprzednia, 1, 2, 3, 4, 5, następna, ostatnia.

    @if (Model != null && Model.pageCount > 1)
    {
    // If there is more than one page of results, show the paging buttons.
    <table>
        <tr>
            <td>
                @if (Model.currentPage > 0)
                {
                    <p class="pageButton">
                        @Html.ActionLink("|<", "Page", "Home", new { paging = "0" }, null)
                    </p>
                }
                else
                {
                    <p class="pageButtonDisabled">|&lt;</p>
                }
            </td>
    
            <td>
                @if (Model.currentPage > 0)
                {
                    <p class="pageButton">
                        @Html.ActionLink("<", "PageAsync", "Home", new { paging = "prev" }, null)
                    </p>
                }
                else
                {
                    <p class="pageButtonDisabled">&lt;</p>
                }
            </td>
    
            @for (var pn = Model.leftMostPage; pn < Model.leftMostPage + Model.pageRange; pn++)
            {
                <td>
                    @if (Model.currentPage == pn)
                    {
                        // Convert displayed page numbers to 1-based and not 0-based.
                        <p class="pageSelected">@(pn + 1)</p>
                    }
                    else
                    {
                        <p class="pageButton">
                            @Html.ActionLink((pn + 1).ToString(), "PageAsync", "Home", new { paging = @pn }, null)
                        </p>
                    }
                </td>
            }
    
            <td>
                @if (Model.currentPage < Model.pageCount - 1)
                {
                    <p class="pageButton">
                        @Html.ActionLink(">", "PageAsync", "Home", new { paging = "next" }, null)
                    </p>
                }
                else
                {
                    <p class="pageButtonDisabled">&gt;</p>
                }
            </td>
    
            <td>
                @if (Model.currentPage < Model.pageCount - 1)
                {
                    <p class="pageButton">
                        @Html.ActionLink(">|", "PageAsync", "Home", new { paging = Model.pageCount - 1 }, null)
                    </p>
                }
                else
                {
                    <p class="pageButtonDisabled">&gt;|</p>
                }
            </td>
        </tr>
    </table>
    }
    

    Używamy tabeli HTML, aby dokładnie wyrównać elementy. Jednak wszystkie akcje pochodzą z @Html.ActionLink instrukcji, każda wywołująca kontroler z nowym modelem utworzonym z różnymi wpisami do właściwości stronicowania , którą dodaliśmy wcześniej.

    Pierwsze i ostatnie opcje strony nie wysyłają ciągów, takich jak "first" i "last", ale zamiast tego wysyłają poprawne numery stron.

  2. Dodaj klasy stronicowania do listy stylów HTML w pliku hotels.css. Klasa pageSelected służy do identyfikowania bieżącej strony (stosując pogrubiony format do numeru strony) na liście numerów stron.

    .pageButton {
        border: none;
        color: darkblue;
        font-weight: normal;
        width: 50px;
    }
    
    .pageSelected {
        border: none;
        color: black;
        font-weight: bold;
        width: 50px;
    }
    
    .pageButtonDisabled {
        border: none;
        color: lightgray;
        font-weight: bold;
        width: 50px;
    }
    

Dodawanie akcji Strona do kontrolera

  1. Otwórz plik HomeController.cs i dodaj akcję PageAsync . Ta akcja odpowiada na dowolną z wybranych opcji strony.

    public async Task<ActionResult> PageAsync(SearchData model)
    {
        try
        {
            int page;
    
            switch (model.paging)
            {
                case "prev":
                    page = (int)TempData["page"] - 1;
                    break;
    
                case "next":
                    page = (int)TempData["page"] + 1;
                    break;
    
                default:
                    page = int.Parse(model.paging);
                    break;
            }
    
            // Recover the leftMostPage.
            int leftMostPage = (int)TempData["leftMostPage"];
    
            // Recover the search text and search for the data for the new page.
            model.searchText = TempData["searchfor"].ToString();
    
            await RunQueryAsync(model, page, leftMostPage);
    
            // Ensure Temp data is stored for next call, as TempData only stores for one call.
            TempData["page"] = (object)page;
            TempData["searchfor"] = model.searchText;
            TempData["leftMostPage"] = model.leftMostPage;
        }
    
        catch
        {
            return View("Error", new ErrorViewModel { RequestId = "2" });
        }
        return View("Index", model);
    }
    

    Metoda RunQueryAsync będzie teraz wyświetlać błąd składniowy z powodu trzeciego parametru, do którego przejdziemy nieco.

    Uwaga

    Wywołania bazy danych TempData przechowują wartość ( obiekt) w magazynie tymczasowym, choć ten magazyn utrzymuje się tylko dla jednego wywołania. Jeśli przechowujemy coś w danych tymczasowych, będzie on dostępny dla następnego wywołania akcji kontrolera, ale na pewno zostanie on odszedł przez wywołanie po tym. Ze względu na tę krótką żywotność przechowujemy właściwości tekstu wyszukiwania i stronicowania z powrotem w magazynie tymczasowym każdy i każdy wywołanie metody PageAsync.

  2. Zaktualizuj akcję Index(model), aby przechowywać zmienne tymczasowe, a następnie dodać parametr strony po lewej stronie do wywołania RunQueryAsync .

    public async Task<ActionResult> Index(SearchData model)
    {
        try
        {
            // Ensure the search string is valid.
            if (model.searchText == null)
            {
                model.searchText = "";
            }
    
            // Make the search call for the first page.
            await RunQueryAsync(model, 0, 0);
    
            // Ensure temporary data is stored for the next call.
            TempData["page"] = 0;
            TempData["leftMostPage"] = 0;
            TempData["searchfor"] = model.searchText;
        }
    
        catch
        {
            return View("Error", new ErrorViewModel { RequestId = "1" });
        }
        return View(model);
    }
    
  3. Metoda RunQueryAsync wprowadzona w poprzedniej lekcji wymaga modyfikacji w celu rozwiązania błędu składni. Używamy pól Skip, Size i IncludeTotalCount klasy SearchOptions , aby zażądać tylko jednej strony wyników, zaczynając od ustawienia Pomiń . Musimy również obliczyć zmienne stronicowania dla naszego widoku. Zastąp całą metodę następującym kodem.

    private async Task<ActionResult> RunQueryAsync(SearchData model, int page, int leftMostPage)
    {
        InitSearch();
    
        var options = new SearchOptions
        {
            // Skip past results that have already been returned.
            Skip = page * GlobalVariables.ResultsPerPage,
    
            // Take only the next page worth of results.
            Size = GlobalVariables.ResultsPerPage,
    
            // Include the total number of results.
            IncludeTotalCount = true
        };
    
        // Add fields to include in the search results.
        options.Select.Add("HotelName");
        options.Select.Add("Description");
    
        // For efficiency, the search call should be asynchronous, so use SearchAsync rather than Search.
        model.resultList = await _searchClient.SearchAsync<Hotel>(model.searchText, options).ConfigureAwait(false);
    
        // This variable communicates the total number of pages to the view.
        model.pageCount = ((int)model.resultList.TotalCount + GlobalVariables.ResultsPerPage - 1) / GlobalVariables.ResultsPerPage;
    
        // This variable communicates the page number being displayed to the view.
        model.currentPage = page;
    
        // Calculate the range of page numbers to display.
        if (page == 0)
        {
            leftMostPage = 0;
        }
        else if (page <= leftMostPage)
        {
            // Trigger a switch to a lower page range.
            leftMostPage = Math.Max(page - GlobalVariables.PageRangeDelta, 0);
        }
        else if (page >= leftMostPage + GlobalVariables.MaxPageRange - 1)
        {
            // Trigger a switch to a higher page range.
            leftMostPage = Math.Min(page - GlobalVariables.PageRangeDelta, model.pageCount - GlobalVariables.MaxPageRange);
        }
        model.leftMostPage = leftMostPage;
    
        // Calculate the number of page numbers to display.
        model.pageRange = Math.Min(model.pageCount - leftMostPage, GlobalVariables.MaxPageRange);
    
        return View("Index", model);
    }
    
  4. Na koniec wprowadź niewielką zmianę w widoku. Zmienna resultList.Results.TotalCount będzie teraz zawierać liczbę wyników zwróconych na jednej stronie (3 w naszym przykładzie), a nie całkowitą liczbę. Ponieważ ustawiliśmy wartość IncludeTotalCount na true, zmienna resultList.TotalCount zawiera teraz łączną liczbę wyników. Zlokalizuj więc, gdzie jest wyświetlana liczba wyników w widoku, i zmień ją na następujący kod.

    // Show the result count.
    <p class="sampleText">
        @Model.resultList.TotalCount Results
    </p>
    
    var results = Model.resultList.GetResults().ToList();
    
    @for (var i = 0; i < results.Count; i++)
    {
        // Display the hotel name and description.
        @Html.TextAreaFor(m => results[i].Document.HotelName, new { @class = "box1" })
        @Html.TextArea($"desc{1}", results[i].Document.Description, new { @class = "box2" })
    }
    

    Uwaga

    Występuje niewielkie trafienie wydajności podczas ustawiania wartości IncludeTotalCount na true, ponieważ ta suma musi być obliczana przez Azure Cognitive Search. W przypadku złożonych zestawów danych istnieje ostrzeżenie, że zwracana wartość jest przybliżeniem. Ponieważ korpus wyszukiwania hotelu jest mały, będzie dokładny.

Kompilowanie i uruchamianie aplikacji

Teraz wybierz pozycję Rozpocznij bez debugowania (lub naciśnij klawisz F5).

  1. Wyszukaj ciąg, który zwraca wiele wyników (np. "wifi"). Czy możesz stronicować starannie wyniki?

    Numerowane stronicowanie za pośrednictwem wyników

  2. Spróbuj kliknąć prawym przyciskiem myszy, a później po lewej stronie najwięcej numerów stron. Czy numery stron są odpowiednio dostosowane do środka strony, na której jesteś?

  3. Czy są przydatne opcje "first" i "last"? Niektóre komercyjne wyszukiwarki używają tych opcji, a inne nie.

  4. Przejdź do ostatniej strony wyników. Ostatnia strona to jedyna strona, która może zawierać mniej niż wyniki ResultsPerPage .

    Badanie ostatniej strony

  5. Wpisz ciąg "town", a następnie kliknij pozycję wyszukaj. Nie są wyświetlane żadne opcje stronicowania, jeśli wyniki są mniejsze niż jedna strona.

    Wyszukiwanie

Zapisz ten projekt i przejdź do następnej sekcji, aby uzyskać alternatywną formę stronicowania.

Rozszerzanie aplikacji przy użyciu nieskończonego przewijania

Nieskończone przewijanie jest wyzwalane, gdy użytkownik przewija pionowy pasek przewijania do ostatniego wyświetlanego wyniku. W tym przypadku zostanie wykonane wywołanie usługi wyszukiwania dla następnej strony wyników. Jeśli nie ma więcej wyników, nic nie zostanie zwrócone, a pionowy pasek przewijania nie zmieni się. Jeśli istnieje więcej wyników, zostaną one dołączone do bieżącej strony, a pasek przewijania zmieni się, aby pokazać, że więcej wyników jest dostępnych.

Ważnym punktem do zapamiętania jest to, że bieżąca strona nie jest zastępowana, ale raczej rozszerzona, aby pokazać dodatkowe wyniki. Użytkownik zawsze może przewijać kopię zapasową do pierwszych wyników wyszukiwania.

Aby zaimplementować nieskończone przewijanie, zacznijmy od projektu przed dodaniu któregokolwiek z elementów przewijania numeru strony. W usłudze GitHub jest to rozwiązanie FirstAzureSearchApp .

Dodawanie pól stronicowania do modelu

  1. Najpierw dodaj właściwość stronicowania do klasy SearchData (w pliku modelu SearchData.cs).

    // Record if the next page is requested.
    public string paging { get; set; }
    

    Ta zmienna jest ciągiem, który zawiera ciąg "dalej", jeśli powinna zostać wysłana następna strona wyników lub ma wartość null dla pierwszej strony wyszukiwania.

  2. W tym samym pliku i w przestrzeni nazw dodaj globalną klasę zmiennych z jedną właściwością. W usłudze MVC zmienne globalne są deklarowane we własnej klasie statycznej. WynikiPerPage ustawia liczbę wyników na stronę.

    public static class GlobalVariables
    {
        public static int ResultsPerPage
        {
            get
            {
                return 3;
            }
        }
    }
    

Dodawanie pionowego paska przewijania do widoku

  1. Znajdź sekcję pliku index.cshtml, który wyświetla wyniki (rozpoczyna się od @if (Model != null)).

  2. Zastąp sekcję poniższym kodem. Nowa <sekcja div> znajduje się wokół obszaru, który powinien być przewijany, i dodaje zarówno atrybut overflow-y , jak i wywołanie funkcji onscroll o nazwie "scrolled()", w następujący sposób.

    @if (Model != null)
    {
        // Show the result count.
        <p class="sampleText">
            @Model.resultList.TotalCount Results
        </p>
    
        var results = Model.resultList.GetResults().ToList();
    
        <div id="myDiv" style="width: 800px; height: 450px; overflow-y: scroll;" onscroll="scrolled()">
    
            <!-- Show the hotel data. -->
            @for (var i = 0; i < results.Count; i++)
            {
                // Display the hotel name and description.
                @Html.TextAreaFor(m => results[i].Document.HotelName, new { @class = "box1" })
                @Html.TextArea($"desc{i}", results[i].Document.Description, new { @class = "box2" })
            }
    
  3. Bezpośrednio pod pętlą po tagu </div> dodaj przewijaną funkcję.

    <script>
        function scrolled() {
            if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
                $.getJSON("/Home/NextAsync", function (data) {
                    var div = document.getElementById('myDiv');
    
                    // Append the returned data to the current list of hotels.
                    for (var i = 0; i < data.length; i += 2) {
                        div.innerHTML += '\n<textarea class="box1">' + data[i] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box2">' + data[i + 1] + '</textarea>';
                    }
                });
            }
        }
    </script>
    

    Instrukcja if w powyższym skry skrycie sprawdza, czy użytkownik przewinął w dół pionowego paska przewijania. Jeśli tak, wywołanie kontrolera home jest wykonywane do akcji o nazwie NextAsync. Kontroler nie potrzebuje żadnych innych informacji, a następnie zwróci następną stronę danych. Te dane są następnie formatowane przy użyciu identycznych stylów HTML jako oryginalnej strony. Jeśli żadne wyniki nie zostaną zwrócone, nic nie zostanie dołączone i elementy pozostaną tak, jak są.

Obsługa akcji Dalej

Do kontrolera należy wysłać tylko trzy akcje: pierwsze uruchomienie aplikacji, która wywołuje metodę Index(), pierwsze wyszukiwanie przez użytkownika, które wywołuje metodę Index(model), a następnie kolejne wywołania w celu uzyskania większej liczby wyników za pośrednictwem metody Next(model).

  1. Otwórz plik kontrolera macierzystego i usuń metodę RunQueryAsync z oryginalnego samouczka.

  2. Zastąp akcję Index(model) następującym kodem. Teraz obsługuje ono pole stronicowania, gdy ma wartość null, lub ma wartość "next" i obsługuje wywołanie Azure Cognitive Search.

    public async Task<ActionResult> Index(SearchData model)
    {
        try
        {
            InitSearch();
    
            int page;
    
            if (model.paging != null && model.paging == "next")
            {
                // Increment the page.
                page = (int)TempData["page"] + 1;
    
                // Recover the search text.
                model.searchText = TempData["searchfor"].ToString();
            }
            else
            {
                // First call. Check for valid text input.
                if (model.searchText == null)
                {
                    model.searchText = "";
                }
                page = 0;
            }
    
            // Setup the search parameters.
            var options = new SearchOptions
            {
                SearchMode = SearchMode.All,
    
                // Skip past results that have already been returned.
                Skip = page * GlobalVariables.ResultsPerPage,
    
                // Take only the next page worth of results.
                Size = GlobalVariables.ResultsPerPage,
    
                // Include the total number of results.
                IncludeTotalCount = true
            };
    
            // Specify which fields to include in results.
            options.Select.Add("HotelName");
            options.Select.Add("Description");
    
            // For efficiency, the search call should be asynchronous, so use SearchAsync rather than Search.
            model.resultList = await _searchClient.SearchAsync<Hotel>(model.searchText, options).ConfigureAwait(false);               
    
            // Ensure TempData is stored for the next call.
            TempData["page"] = page;
            TempData["searchfor"] = model.searchText;
        }
        catch
        {
            return View("Error", new ErrorViewModel { RequestId = "1" });
        }
    
        return View("Index", model);
    }
    

    Podobnie jak w przypadku metody stronicowania numerowanego, używamy ustawień wyszukiwania Pomiń i Rozmiar , aby zażądać tylko potrzebnych danych.

  3. Dodaj akcję NextAsync do kontrolera macierzystego. Zwróć uwagę, jak zwraca listę, każdy hotel dodaje dwa elementy do listy: nazwę hotelu i opis hotelu. Ten format jest ustawiony tak, aby był zgodny z użyciem zwróconych danych w widoku przez funkcję przewijaną .

    public async Task<ActionResult> NextAsync(SearchData model)
    {
        // Set the next page setting, and call the Index(model) action.
        model.paging = "next";
        await Index(model).ConfigureAwait(false);
    
        // Create an empty list.
        var nextHotels = new List<string>();
    
        // Add a hotel name, then description, to the list.
        await foreach (var searchResult in model.resultList.GetResultsAsync())
        {
            nextHotels.Add(searchResult.Document.HotelName);
            nextHotels.Add(searchResult.Document.Description);
        }
    
        // Rather than return a view, return the list of data.
        return new JsonResult(nextHotels);
    }
    
  4. Jeśli wystąpi błąd składni w ciągu> listy<, dodaj następującą dyrektywę using do nagłówka pliku kontrolera.

    using System.Collections.Generic;
    

Kompilowanie i uruchamianie projektu

Teraz wybierz pozycję Rozpocznij bez debugowania (lub naciśnij klawisz F5).

  1. Wprowadź termin, który da mnóstwo wyników (na przykład "pula"), a następnie przetestuj pionowy pasek przewijania. Czy wyzwala nową stronę wyników?

    Nieskończone przewijanie wyników

    Porada

    Aby upewnić się, że na pierwszej stronie pojawi się pasek przewijania, pierwsza strona wyników musi nieznacznie przekroczyć wysokość wyświetlanego obszaru. W naszym przykładzie pole .box1 ma wysokość 30 pikseli, pole .box2 ma wysokość 100 pikseli i dolny margines 24 pikseli. Każdy wpis używa więc 154 pikseli. Trzy wpisy zajmują 3 x 154 = 462 piksele. Aby upewnić się, że zostanie wyświetlony pionowy pasek przewijania, należy ustawić wysokość obszaru wyświetlania, która jest mniejsza niż 462 piksele, nawet 461 działa. Ten problem występuje tylko na pierwszej stronie, po upływie którego na pewno pojawi się pasek przewijania. Wiersz do aktualizacji to: <div id="myDiv" style="width: 800px; height: 450px; overflow-y: scroll;" onscroll="scrolled()">.

  2. Przewiń w dół do dołu wyników. Zwróć uwagę, że wszystkie informacje są teraz na stronie jednego widoku. Możesz przewinąć całą drogę do góry bez wyzwalania wywołań serwera.

Bardziej zaawansowane nieskończone systemy przewijania mogą używać kółka myszy lub podobnego innego mechanizmu, aby wyzwolić ładowanie nowej strony wyników. Nie będziemy robić nieskończonego przewijania w kolejnych samouczkach, ale ma pewien urok, ponieważ pozwala uniknąć dodatkowych kliknięć myszą i możesz dokładniej zbadać inne opcje.

Wnioski

Rozważ następujące wnioski z tego projektu:

  • Stronicowanie numerowane jest przydatne w przypadku wyszukiwań, w których kolejność wyników jest nieco arbitralna, co oznacza, że użytkownicy mogą zainteresować się kolejnymi stronami.
  • Nieskończone przewijanie jest przydatne, gdy kolejność wyników jest szczególnie ważna. Jeśli na przykład wyniki są uporządkowane w odległości od centrum miasta docelowego.
  • Stronicowanie numerowane umożliwia lepszą nawigację. Na przykład użytkownik może pamiętać, że interesujący wynik znajdował się na stronie 6, natomiast w nieskończonym przewijaniu nie istnieje takie łatwe odwołanie.
  • Nieskończone przewijanie ma łatwy apel, przewijanie w górę i w dół bez numerów stron do kliknięcia.
  • Kluczową funkcją nieskończonego przewijania jest to, że wyniki są dołączane do istniejącej strony, a nie zastępują tej strony, co jest wydajne.
  • Magazyn tymczasowy jest utrwalany tylko dla jednego wywołania i musi zostać zresetowany, aby przetrwać dodatkowe wywołania.

Następne kroki

Stronicowanie ma podstawowe znaczenie dla środowiska wyszukiwania. W przypadku dobrze omówionego stronicowania następnym krokiem jest dalsze ulepszanie środowiska użytkownika przez dodanie wyszukiwania z wyprzedzeniem.