WordPress REST API Ajax显示更多帖子按钮

时间:2019-02-24 21:38:32

标签: javascript jquery wordpress

PHP / HTML:

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

JavaScript:

(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);

这是麻烦的部分,它不会删除链接。

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

到达帖子结尾后,单击“加载更多”链接时出现控制台错误:

  

400错误的请求
请求的页数大于可用的页数。

2 个答案:

答案 0 :(得分:1)

问题似乎是对该端点的无效查询,因此在这种情况下永远不会运行success: function()


添加到所有API错误

您可以为所有此类错误添加相同的功能...

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

尽管可能不是处理所有错误的理想方式。


测试现有错误消息

另一种选择是,如果在收到该确切消息的错误时删除按钮...

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

,但是如果对该错误消息进行任何更改,它很容易被破坏。


从API返回自定义错误代码

建议的处理方式是返回特定的错误代码(以及HTTP状态代码400),以更可靠的格式指定确切的情况...

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

以下是有关如何在API中配置错误处理的示例:Best Practices for API Error Handling


返回200 HTTP状态代码

最后一个选择是通过返回200级的HTTP状态代码来更改API端点处理这种“错误” /情况的方式,该状态代码将调用success:而不是而是使用error:回调。

答案 1 :(得分:1)

我找到了两种解决方法:

使用数据属性

获取模板中的最大页面数,将其分配给data属性,然后在脚本中访问它。然后对照总页数检查当前页面,并在到达最后一页时将“加载更多”按钮设置为禁用状态。

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>

JavaScript:

(function($) {
    const loadMoreButton = $('#ajax-button');
    const loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        const endpoint = loadMoreButton.data('endpoint');
        const ppp = loadMoreButton.data('ppp');
        const 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);

使用jQuery complete事件

从HTTP响应标头中获取总页数x-wp-totalpages。然后在到达最后一页时更改按钮状态。

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>

JavaScript:

(function($) {
    const loadMoreButton = $('#ajax-button');
    const loadMoreContainer = $('#ajax-content');
    if (loadMoreButton) {
        const endpoint = loadMoreButton.data('endpoint');
        const 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);