简体   繁体   中英

How do I load specific data via jQuery Ajax in this Codeigniter application, instead of the entire page?

I have been working on an online newspaper/blogging application with CodeIgniter 3.1.8 and Twitter Bootstrap 4. I am currently working on a lazy loading (of posts) feature.

By default, the posts are paginated and displayed 12 at a time , at http://myblog.com/ , http://myblog.com/?page=2 , and so on.

In application\\controllers\\Posts.php I have

private function _initPagination($path, $totalRows, $query_string_segment = 'page')
{
    //load and configure pagination 
    $this->load->library('pagination');
    $config['base_url']             = base_url($path);
    $config['query_string_segment'] = $query_string_segment;
    $config['enable_query_strings'] = TRUE;
    $config['reuse_query_string']   = TRUE;
    $config['total_rows']           = $totalRows;
    $config['per_page']             = 12;

    if($this->Static_model->get_static_data()['has_pager']){
        $config['display_pages'] = FALSE;
        $config['first_link'] = FALSE;
        $config['last_link'] = FALSE;
        $config['prev_tag_open'] = '<li class="prev">';
        $config['prev_tag_close'] = '</li>';
        $config['next_tag_open'] = '<li class="next">';
        $config['next_tag_close'] = '</li>';
    }

    if (!isset($_GET[$config['query_string_segment']]) || $_GET[$config['query_string_segment']] < 1) {
        $_GET[$config['query_string_segment']] = 1;
    }
    $this->pagination->initialize($config);
    
    $limit  = $config['per_page'];
    $offset = ($this->input->get($config['query_string_segment']) - 1) * $limit;
    
    return array(
        'limit' => $limit,
        'offset' => $offset
    );
}

public function index()
{
    //call initialization method
    $config = $this->_initPagination("/", $this->Posts_model->get_num_rows());
    $data                  = $this->Static_model->get_static_data();
    $data['base_url']      = base_url("/");
    $data['pages']         = $this->Pages_model->get_pages();
    $data['categories']    = $this->Categories_model->get_categories();
    $data['search_errors'] = validation_errors();
    
    //use limit and offset returned by _initPaginator method
    $data['posts'] = $this->Posts_model->get_posts($config['limit'], $config['offset']);
    $this->twig->addGlobal('pagination', $this->pagination->create_links());
    
    // featured posts
    if ($data['is_featured']) {
        $data['featured'] = $this->Posts_model->featured_posts();
        $this->twig->addGlobal('featuredPosts', "themes/{$data['theme_directory']}/partials/hero.twig");
    }
    
    $this->twig->display("themes/{$data['theme_directory']}/layout", $data);
} 

In order to load the posts via jQuery Ajax instead, I have:

(function($) {

    var currentPage = 1;

    // Hide pahination
    $('.pagination').hide();

    $(window).scroll(function() {
        if ($(window).scrollTop() >= $(document).height() - $(window).height() - 10) {
            loadMore();
        }
    });

    function loadMore() {
        $.ajax({
                url: baseUrl + '?page=' + currentPage,
                type: 'POST',
                beforeSend: function() {
                    $('.loader').show();
                }
            })
            .done(function(data) {
                $('.loader').hide();
                // Append new posts to the posta container
                $("#postsContainer").append(data);
                currentPage = currentPage + 1;
            });
    }

})(jQuery);

The HTML

<div class="col-lg-8 col-md-10 mx-auto" id="postsContainer">
  <div class="post-preview">
    <a href="http://myblog.com/learn-to-code-with-us-for-a-better-future">
      <h2 class="post-title">Learn to code with us, for a better future</h2>
      <h3 class="post-subtitle">Learn to code with us. We have the best teachers in the country.</h3>
    </a>
    <p class="post-meta">
      Posted in <a href="http://myblog.com/categories/posts/1" title="All posts in Uncategorized">Uncategorized</a>, on Nov 19, 2019
    </p>
  </div>
  <hr>
  ...
</div>

The problem

For a reason I have not been able to figure out, when I scroll to the bottom of the page, instead of the posts to be appended to the posts container, the entire page is appended.

Where is my mistake?

You seem to be trying to reload the entire page with paginated data - that's a really bad practice. In the long run, you'll end up with slower pages that way.

You would be better off having a separate endpoint for your AJAX that outputs a JSON array of HTML strings, one for each post. This is still slower than using a 2-tier solution like Codeigniter and React, but it's certainly faster than constantly rerendering the entire UI.

I got a working solution:

(function($) {

    var currentPage = 2,
        maxPage = $('#postsContainer').data('max-page'),
        posts = null;

    $('.pagination').hide();

    $(window).scroll(function() {
        var toBottom = $(window).scrollTop() >= $(document).height() - $(window).height() - 25;

        if (toBottom && currentPage <= maxPage) {
            loadMore();
        }
    });

    function loadMore() {
        $.ajax({
                url: baseUrl + '?page=' + currentPage,
                type: 'GET',
                beforeSend: function() {
                    if (typeof posts != 'undefined') {
                        $('.loader').show();
                    }
                }
            })
            .done(function(data) {
                $('.loader').hide();
                posts = $(data).find('#postsContainer').html();

                if (typeof posts != 'undefined') {
                    $('#postsContainer').append(posts);
                    currentPage = currentPage + 1;

                    if (currentPage > maxPage) {
                        $('#postsContainer').append('<p class="text-center text-muted">No more posts to load</p>');
                    }
                }
            });
    }

})(jQuery);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM