PHP / HTML:

<ul id="load-more-div"></ul>
<a id="load-more" data-ppp="<?php echo get_option('posts_per_page'); ?>">load more</a>

JavaScripts:

(function($) {
  // Grab the load more button, since I only want to run the code if the button is on the page
  var loadMoreButton = $("#load-more");

  if (loadMoreButton) {
    // Get the posts_per_page number set in Reading Options
    var ppp = loadMoreButton.data("ppp");

    // Initialize function
    var loadPosts = function(page) {
      var theData, loadMoreContainer, errorStatus, errorMessage;

      // The AJAX request
      $.ajax({
        url: "/wp-json/wp/v2/posts",
        dataType: "json",
        data: {
          // Match the query that was already run on the page
          per_page: ppp,
          page: page,
          type: "post",
          orderby: "date"
        },
        success: function(data) {
          // Remove the button if the response returns no items
          if (data.length < 1) {
            loadMoreButton.remove();
          }

          // Create a place to store exactly what I need
          // Alternatively, the response can be filtered to only return the needed data, which is probably more efficient as the following loop wont be needed
          theData = [];

          // Get only what I need, and store it
          for (i = 0; i < data.length; i++) {
            theData[i] = {};
            theData[i].id = data[i].id;
            theData[i].link = data[i].link;
            theData[i].title = data[i].title.rendered;
            theData[i].content = data[i].content.rendered;
          }

          // Grab the container where my data will be inserted
          loadMoreContainer = $("#load-more-div");

          // For each object in my newly formed array, build a new element to store that data, and insert it into the DOM
          $.each(theData, function(i) {
            loadMoreContainer.append(
              '<li><a href="' +
                theData[i].link +
                '">' +
                theData[i].title +
                "</a></li>"
            );
          });
        },
        error: function(jqXHR, textStatus, errorThrown) {
          errorStatus = jqXHR.status + " " + jqXHR.statusText + "\n";
          errorMessage = jqXHR.responseJSON.message;

          // Show me what the error was
          console.log(errorStatus + errorMessage);
        }
      });
    };

    // Since our AJAX query is the same as the original query on the page (page 1), start with page 2
    var getPage = 2;

    // Actually implement the functionality when the button is clicked
    loadMoreButton.on("click", function() {
      loadPosts(getPage);
      // Increment the page, so on the next click we get the next page of results
      getPage++;
    });
  }
})(jQuery);

To jest część problemu, nie usuwa linku.

// Remove the button if the response returns no items
if (data.length < 1) {
  loadMoreButton.remove();
}

Błędy konsoli Po kliknięciu Załaduj więcej linku po osiągnięciu końca postów:

400 złej prośby
Żądany numer strony jest większy niż liczba dostępnych stron.

1
Stickers 25 luty 2019, 00:38

2 odpowiedzi

Najlepsza odpowiedź

Znalazłem dwa sposoby rozwiązania tego:

### Korzystanie z atrybutu danych

Uzyskaj maksymalną liczbę stron w szablonie, przypisz go do atrybutu danych i uzyskaj dostęp do niego w skryptach. Następnie sprawdź bieżącą stronę na całkowitą numery stron, a następnie ustawić osoby niepełnosprawne do przycisku Załaduj więcej, gdy osiągnie ostatnią stronę.

PHP / HTML:

<ul id="ajax-content"></ul>

<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>" data-pages="<?php echo $wp_query->max_num_pages; ?>">Show more</button>

JavaScripts:

(function($) {
    var loadMoreButton = $('#ajax-button');
    var loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        var endpoint = loadMoreButton.data('endpoint');
        var ppp = loadMoreButton.data('ppp');
        var pages = loadMoreButton.data('pages');
        var loadPosts = function(page) {
            var theData, errorStatus, errorMessage;
            $.ajax({
                url: endpoint,
                dataType: 'json',
                data: {
                    per_page: ppp,
                    page: page,
                    type: 'post',
                    orderby: 'date'
                },
                beforeSend: function() {
                    loadMoreButton.attr('disabled', true);
                },
                success: function(data) {
                    theData = [];
                    for (i = 0; i < data.length; i++) {
                        theData[i] = {};
                        theData[i].id = data[i].id;
                        theData[i].link = data[i].link;
                        theData[i].title = data[i].title.rendered;
                        theData[i].content = data[i].content.rendered;
                    }
                    $.each(theData, function(i) {
                        loadMoreContainer.append('<li><a href="' + theData[i].link + '">' + theData[i].title + '</a></li>');
                    });
                    loadMoreButton.attr('disabled', false);
                    if (getPage == pages) {
                        loadMoreButton.attr('disabled', true);
                    }
                    getPage++;
                },
                error: function(jqXHR) {
                    errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
                    errorMessage = jqXHR.responseJSON.message;
                    console.log(errorStatus + errorMessage);
                }
            });
        };
        var getPage = 2;
        loadMoreButton.on('click', function() {
            loadPosts(getPage);
        });
    }
})(jQuery);

### za pomocą jQuery complete wydarzenie

Uzyskaj łączne strony x-wp-totalpages z nagłówków odpowiedzi HTTP. Następnie zmień stany przycisków po osiągnięciu ostatniej strony.

PHP / HTML:

<ul id="ajax-content"></ul>

<button type="button" id="ajax-button" data-endpoint="<?php echo get_rest_url(null, 'wp/v2/posts'); ?>" data-ppp="<?php echo get_option('posts_per_page'); ?>">Show more</button>

JavaScripts:

(function($) {
    var loadMoreButton = $('#ajax-button');
    var loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        var endpoint = loadMoreButton.data('endpoint');
        var ppp = loadMoreButton.data('ppp');
        var pager = 0;
        var loadPosts = function(page) {
            var theData, errorStatus, errorMessage;
            $.ajax({
                url: endpoint,
                dataType: 'json',
                data: {
                    per_page: ppp,
                    page: page,
                    type: 'post',
                    orderby: 'date'
                },
                beforeSend: function() {
                    loadMoreButton.attr('disabled', true);
                },
                success: function(data) {
                    theData = [];
                    for (i = 0; i < data.length; i++) {
                        theData[i] = {};
                        theData[i].id = data[i].id;
                        theData[i].link = data[i].link;
                        theData[i].title = data[i].title.rendered;
                        theData[i].content = data[i].content.rendered;
                    }
                    $.each(theData, function(i) {
                        loadMoreContainer.append('<li><a href="' + theData[i].link + '">' + theData[i].title + '</a></li>');
                    });
                    loadMoreButton.attr('disabled', false);
                },
                error: function(jqXHR) {
                    errorStatus = jqXHR.status + ' ' + jqXHR.statusText + '\n';
                    errorMessage = jqXHR.responseJSON.message;
                    console.log(errorStatus + errorMessage);
                },
                complete: function(jqXHR) {
                    if (pager == 0) {
                        pager = jqXHR.getResponseHeader('x-wp-totalpages');
                    }
                    pager--;
                    if (pager == 1) {
                        loadMoreButton.attr('disabled', true);
                    }
                }
            });
        };
        var getPage = 2;
        loadMoreButton.on('click', function() {
            loadPosts(getPage);
            getPage++;
        });
    }
})(jQuery);
2
Stickers 4 grudzień 2020, 16:30

Problem wydaje się być nieprawidłowym zapytaniem do tego punktu końcowego, dzięki czemu success: function() nigdy nie będzie działać w tej sytuacji.


Dodaj do wszystkich błędów API

Możesz dodać tę samą funkcjonalność dla wszystkich takich błędów ...

  error: function(jqXHR, textStatus, errorThrown) {
      loadMoreButton.remove();
      ....
  }

Choć może nie być pożądanym sposobem obsługi błędów wszystkie .


Testuj na istniejący komunikat o błędzie

Inną opcją może być usunięcie przycisku, jeśli pojawi się błąd z dokładną wiadomością ...

  error: function(jqXHR, textStatus, errorThrown) {
      if (jqXHR.statusText === 'The page number requested is larger than the number of pages available.') {
         loadMoreButton.remove();
      }
      ....
  }

Ale byłoby to podatne na złamanie z jakichkolwiek zmian w tym komunikatu o błędzie.


Zwróć niestandardowy kod błędu z API

Zalecany sposób na obsługę, byłoby zwrócenie określonego kodu błędu (wraz z kodem stanu HTTP 400), aby określić dokładną sytuację w bardziej niezawodnym formacie ...

  error: function(jqXHR, textStatus, errorThrown) {
      if (jqXHR.statusCode === '215') {
         loadMoreButton.remove();
      }
      ....
  }

Oto przykład, w jaki sposób skonfigurować obsługę błędów w API: Najlepsze praktyki dotyczące błędu API Obsługa.


Zwróć kod stanu HTTP 200

Ostatnia opcja byłaby zmienić sposób, w jaki proces końcowy API obsługuje ten typ "Błąd" / sytuacji, zwracając zamiast tego kodu stanu HTTP 200, który wywołałby success: zamiast success: X2}} Zamiast tego.

1
cantuket 24 luty 2019, 22:26