代码之家  ›  专栏  ›  技术社区  ›  E.Owen

使用AJAX加载更多产品

  •  1
  • E.Owen  · 技术社区  · 6 年前

    我使用AJAX在WooCommerce存档中加载更多的产品。我曾经用AJAX“加载更多”过一次 this page WP_Query 适合我需要的论据。我不明白为什么我的代码不起作用。

    JS公司

    /**
     * AJAX Load (Lazy Load) events
     */
    
    $('#load-more').click( function(e){
        e.preventDefault();
        ajax_next_posts()
        $('body').addClass('ajaxLoading');
    });
    
    var ajaxLock = false; // ajaxLock is just a flag to prevent double clicks and spamming
    
    if( !ajaxLock ) {
    
    function ajax_next_posts() {
    
        ajaxLock = true;
    
        // How many posts there's total
        var totalPosts = parseInt( jQuery( '#found-posts' ).text() );
    
        // How many have been loaded
        var postOffset = jQuery( 'li.product' ).length
    
        // How many do you want to load in single patch
        var postsPerPage = 1;
    
        // Ajax call itself
        $.ajax({
            method: 'POST',
            url: leafshop.ajax_url,
            data: {
                action: 'ajax_next_posts',
                post_offset: postOffset,
                posts_per_page: postsPerPage,
                product_cat: cat_id
            },
            dataType: 'json'
        })
        .done( function( response ) { // Ajax call is successful
            // console.log( response );
    
            // Add new posts
            jQuery( '.product-grid' ).append( response[0] );
    
            // Log SQL query
            jQuery( '#query > pre' ).text( response[2] );
    
            // Update the count of total posts
            // jQuery( '#found-posts' ).text( response[1] );
    
            ajaxLock = false;
    
            console.log( 'Success' );
    
            $('body').removeClass('ajaxLoading');
    
            // How many posts there's total
            var totalPosts = parseInt( jQuery( '#found-posts' ).text() );
            console.log( "Total Posts: " + totalPosts );
    
            // How many have been loaded
            var postOffset = jQuery( 'li.product' ).length
                console.log( "Posts currently showing: " + postOffset );
    
            // Hide button if all posts are loaded
            if( totalPosts < postOffset + ( 1 * postsPerPage ) ) {
                jQuery( '#load-more' ).fadeOut();
            }
    
        })
        // .fail( function() {
        .fail( function(jqXHR, textStatus, errorThrown) { // Ajax call is not successful, still remove lock in order to try again
    
            ajaxLock = false;
    
            console.log(XMLHttpRequest);
            console.log(textStatus);
            console.log(errorThrown);
    
            console.log( 'Failed' );
    
        });
    }
    }
    

    菲律宾比索

    <?php
    
    /**
     * Load next 12 products using AJAX
     */
    function ajax_next_posts() {
        global $wpdb;
        // Build query
        $args = array(
            'post_type' =>  'product'
        );
    // Get offset
    if( !empty( $_POST['post_offset'] ) ) {
    
        $offset = $_POST['post_offset'];
        $args['offset'] = $offset;
    
        // Also have to set posts_per_page, otherwise offset is ignored
        $args['posts_per_page'] = 12;
    }
    
    // Get posts per page
    if( !empty( $_POST['posts_per_page'] ) ) {
        // Also have to set posts_per_page, otherwise offset is ignored
        $args['posts_per_page'] = $_POST['posts_per_page'];
    }
    
    // Set tax query if on cat page
    if( !empty( $_POST['product_cat'] ) ){
        $args['tax_query'] = array(
                                'taxonomy'          =>  'product_cat',
                                'terms'             =>  array( (int)$_POST['product_cat'] ),
                                'field'             =>  'id',
                                'operator'          =>  'IN',
                                'include_children'  =>  1
                            );
    }
    
    $count_results = '0';
    
    $ajax_query = new WP_Query( $args );
    
    // Results found
    if ( $ajax_query->have_posts() ) {
        $count_results = $ajax_query->found_posts;
    
        // Start "saving" results' HTML
        $results_html = '';
        ob_start();
    
        while( $ajax_query->have_posts() ) { 
            $ajax_query->the_post();
            echo wc_get_template_part( 'content', 'product' );
        }
    
        // "Save" results' HTML as variable
        $results_html = ob_get_clean();
    }
    
    // Build ajax response
    $response = array();
    
    // 1. value is HTML of new posts and 2. is total count of posts
    global $wpdb;
    array_push ( $response, $results_html, $count_results, $wpdb->last_query );
    echo json_encode( $response );
    
    // Always use die() in the end of ajax functions
    die();  
    }
    add_action('wp_ajax_ajax_next_posts', 'ajax_next_posts');
    add_action('wp_ajax_nopriv_ajax_next_posts', 'ajax_next_posts');
    

    AJAX调用运行成功,但没有返回我期望的结果。我希望它返回当前类别的下一个产品,而不是返回其他类别的产品。开发现场可通过 http://leaf.kalodigital.co.uk "Black Tea"

    1 回复  |  直到 6 年前
        1
  •  5
  •   E.Owen    6 年前

    方法

    经过进一步的研究,我发现WooCommerce包含一个类名 WC_Poduct_Query 从某种意义上说,它是在查询正确的产品,并将我期望的产品作为一个数组返回 WC_Product_Variable 物体。我接着说,不到一分钟 foreach setup_postdata( $post ); 设置产品对象以便我可以使用 wc_get_template_parts(); content-product.php 格式化数据输出的模板。我发现这不起作用,尽管我不明白为什么会这样,使用 setup-postdata(); 使物体变成 [{id:0,filter:raw},{id:0,filter:raw}] . 我想这和 WC\产品\变量 setup_postdata(); WP_Post

    尽管如此,我还是使用了 WP_Query 对于我的查询,从头开始重建了查询脚本,您相信吗,一切都按预期进行了。下面是我在AJAX上加载下一批产品的工作代码 点击一个按钮,进入商业档案页面。

    JS公司

    /**
     * AJAX Load (Lazy Load) events
     */
    
     //--   Settings
    
    // How many do you want to load each button click?
    var postsPerPage = 12;
    
    //--    /Settings
    
    // How many posts there's total
    var totalPosts = parseInt( jQuery( '#found-posts' ).text() );
    
    // if( totalPosts == postOffset ) {
    //  jQuery( '#load-more' ).fadeOut();
    // }
    
    $('#load-more').click( function(e){
        e.preventDefault();
    
        // Get current category
        var cat_id  =   $(this).data('product-category');
    
    
    ajax_next_posts( cat_id );
        $('body').addClass('ajaxLoading');
    });
    
    var ajaxLock = false; // ajaxLock is just a flag to prevent double clicks and spamming
    
    if( !ajaxLock ) {
    
        function ajax_next_posts( cat_id ) {
    
            ajaxLock = true;
    
            // How many have been loaded
            var postOffset = jQuery( 'li.product' ).length;
    
            // Ajax call itself
            $.ajax({
                method: 'POST',
                url: leafshop.ajax_url,
                data: {
                    action: 'ajax_next_posts',
                    post_offset: postOffset,
                    posts_per_page: postsPerPage,
                    product_cat: cat_id
                },
                dataType: 'json'
            })
            .done( function( response ) { // Ajax call is successful
    
                // Add new posts
                jQuery( '.product-grid' ).append( response[0] );
    
                // Update Post Offset
                var postOffset = jQuery( 'li.product' ).length;
    
                ajaxLock = false;
    
                console.log( 'Success' );
    
                $('body').removeClass('ajaxLoading');
    
                // How many posts there's total
                console.log( "Total Posts: " + totalPosts );
    
                // How many have been loaded
                var postOffset = jQuery( 'li.product' ).length
                console.log( "Posts on Page: " + postOffset );
    
                // Hide button if all posts are loaded
                if( ( totalPosts - postOffset ) <= 0 ) {
                    jQuery( '#load-more' ).fadeOut();
                }
    
            })
            // .fail( function() {
            .fail( function(jqXHR, textStatus, errorThrown) { // Ajax call is not successful, still remove lock in order to try again
    
                ajaxLock = false;
    
                console.log(XMLHttpRequest);
                console.log(textStatus);
                console.log(errorThrown);
    
                console.log( 'Failed' );
    
            });
        }
    }
    

    菲律宾比索

    <?php
    
    /**
     * Load next 12 products using AJAX
     */
    function ajax_next_posts() {
    global $product;
    // Build Query
        $args = array(
                'post_type'             =>  'product',
                'posts_per_page'        =>  (int)$_POST['posts_per_page'],
                'orderby'               =>  'title',
                'order'                 =>  'ASC',
                'offset'                =>  (int)$_POST['post_offset'],
            );
    
    if( !empty( $_POST['product_cat'] ) ) {
        $args['tax_query'] = array(
                                'relation'  => 'AND',
                                    array (
                                        'taxonomy'  =>  'product_cat',
                                        'field' =>  'slug',
                                        'terms' => $_POST['product_cat'],
                                        'operator'  =>  'IN'
                                    ),
                            );
    }
    
    $count_results = '0';
    
    $ajax_query = new WP_Query( $args );
    
    // Results found
    if( $ajax_query->have_posts() ){
    
        // Start "saving" results' HTML
        $results_html = '';
        ob_start();
    
        while( $ajax_query->have_posts() ) {
    
            $ajax_query->the_post();
            echo wc_get_template_part( 'content', 'product' );
    
        }
        wp_reset_postdata();
    
        // "Save" results' HTML as variable
        $results_html = ob_get_clean();
    
    } else {
    
        // Start "saving" results' HTML
        $results_html = '';
        ob_start();
    
        echo "none found!";
    
        // "Save" results' HTML as variable
        $results_html = ob_get_clean();
    
    }
    
    // Build ajax response
    $response = array();
    
    // 1. value is HTML of new posts and 2. is total count of posts
    array_push ( $response, $results_html );
    echo json_encode( $response );
    
    // Always use die() in the end of ajax functions
    die();
    }
    add_action('wp_ajax_ajax_next_posts', 'ajax_next_posts');
    add_action('wp_ajax_nopriv_ajax_next_posts', 'ajax_next_posts');
    

    通过重构提供的AJAX代码,可以将此解决方案转变为“无限滚动”系统,而不是“加载更多”按钮解决方案。请随时重用此代码,它可能认为合适的地方!