仅在JSON对象中使用几个元素

时间:2018-03-07 20:45:03

标签: javascript php jquery json laravel

我使用的是Laravel 5.5。*和jQuery(jquery-3.3.1.min.js)。

我在PHP中进行商业开发(例如95%的时间),所以使用jQuery对我来说真的不同,所以我需要帮助。

我正在开发博客的目标网页,我必须在其中展示3个帖子。在它的底部,我有一个按钮<a>,它应该加载3个帖子并显示给用户。每次用户点击此按钮时,页面中都必须加载3个帖子。

到目前为止,我有以下代码。

帖子控制器

public function index() {
     // this loads the landing page with 3 initial posts
     // Working like a charm

    $posts = Posts::with('categories', 'user', 'media')
        ->where('status', 1)
        ->orderBy('published', 'desc')
        ->limit(3)
    ->get();

     $rank = self::blogPanel();

    return view('portal.pages.blog',
        compact(
            'rank',
            'posts'
        )
    );
}

我从路线中调用此动作

Route::get('/', 'User\PostsController@index')->name('landingPage');

对于我加载更多帖子的逻辑,我有以下内容:

帖子控制器

public function loadMore() {
    $posts = Post::with('categories', 'user', 'media')
        ->where('status', 1)
        ->orderBy('publicacao', 'desc')
        // ->limit(3) I took this out because I was trying to set the limit in front-end
    ->get();

    return json_decode($posts);
}

返回以下内容:

array:48 [▼
  0 => {#257 ▼
    +"id": 48
    +"title": "Lorem ipsum"
    +"summary": "Perferendis labore veritatis voluptas et vero libero fuga qui sapiente maiores animi laborum similique sunt magni voluptate et."
    +"content": """
      Really long text here, with line-breaks and all
      """
    +"seo_id": null
    +"url": "Sunt rerum nisi non dolores."
    +"link_title": "dolor"
    +"published": "2018-03-01 10:35:12"
    +"scheduled": "2018-03-01 10:25:12"
    +"user_id": 1
    +"media_id": null
    +"status": 1
    +"created_at": "2018-03-01 10:25:12"
    +"updated_at": "2018-03-01 10:25:12"
    +"category_id": 3
    +"slug": "cum-aut-officia-consequatur-dolor"
    +"categories": []
    +"user": {#313 ▼
      +"id": 1
      +"name": "Jonessy"
      +"email": "jonessy@email.com"
      +"status": 1
      +"grupo_id": 1
      +"created_at": null
      +"updated_at": null
    }
    +"media": null
  }
  1 => {#341 ▶}
  2 => {#254 ▶}
]

请注意我使用json_decode(),因为在前端使用它看起来更容易。

这是我的刀片文件,我应该打印结果

blogPost.blade.php

@foreach($posts as $post)
    @php
        $date = date_create($post->published);
    @endphp
    <div class="blog-post" id="blog-post">
        <div class="blog-post__title" >
            <h3 id="artTitle">
                {{ $post->title }}
            </h3>
            @foreach($post->categories as $cat)
                <span class="blog-post__category"> {{ $cat->name }} </span>
            @endforeach
            <span class="blog-post__date" id="artDate">
                {{ date_format($date,"d/m/y - H") }}H
            </span>
        </div>
        <div class="blog-post__image" id="artImage">
            @if(isset($post->media_id))
                <img src="{{ asset('img/post-img/' . $post->media->file) }}">
            @else
                <img src="{{asset('img/post-img/default-img-post.jpg')}}">
            @endif
        </div>
        <div class="blog-post__resume">
            <p id="artSumma">
                {{ $post->summary }}
            </p>
        </div>
        <div class="blog-post__link">
            <a href="{{ route('blogPost', $post->slug) }}">
                Read More
            </a>
        </div>
        <div class="blog-post__social">
            // Some social media links for sharing
        </div>
    </div>
@endforeach

我使用loadMore()路由从PostsController调用GET方法:

Route::get('/', 'User\PostsController@loadMore')->name('loadMore');

对于jQuery,这是我到目前为止的代码:

<script type="text/javascript">
    // after importing jquery file...

    $(document).on('click', '#loadingPosts', function(e) {
        e.preventDefault();

        var listing = {!! $posts !!};
        console.log("list ", listing);

        var lastId = listing[2].id;
        console.log("id from pos 2, listing  ", lastId);

        var parts = $(listing).slice(lastId);
        console.log("part  ", parts);
        // THIS DOESN'T WORK, BY THE WAY

        // var lastId = listing[2].id;
        // console.log("listing 2 id", lastId);

        $('#loadingPosts').html("Loading More Posts");

        $.ajax({
            url: '{{ route('loadMore') }}',
            method: 'GET',
            // data: {
            //     'id': lastId,
            // I was trying to set up an ID here, but it didn't work as well
            // },
            // contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(data) {
                // console.log("checking if data not null", data);
                // this returns the expected $posts array

                $('#blog-post').html(data);
                // using .html() because .append() didn't work, which is weird, I guess
                console.log("data depois do apend", data);
                // This returns the same $posts array

                lastId = data[2].id; 
                console.log("last id from data", lastId);
                // I can retrieve the id from the given position from the array.
                // I was trying to set up the id here so I could check, with jQuery, the last post iterated, so I could continue from that point forward

                $('#loadingPosts').html("load More");

                return data[2].id;
                // A last minute despair
            }

        });
    });
</script>

嗯,它不起作用(这就是我在这里的原因)。我真的不知道我做错了什么,因为$posts数组正在传递......

我需要帮助。

值得一提的是:

  • Laravel带有默认分页,但它可以正常工作&#34;水平&#34;并且项目要求&#34;垂直&#34;分页。

  • 页面必须加载&#34;加载更多&#34;按钮,因为页脚有一些非常需要的信息,因此内容无法自动加载

  • 如果有一种方法可以使用vanilla JavaScript或使用Laravel的PHP方法(除了分离方法,之前已经说过),我会非常高兴

提前谢谢大家。

2 个答案:

答案 0 :(得分:0)

public function loadMore(Request $request) {
    $posts = Post::with('categories', 'user', 'media')
        ->where('status', 1)
        ->orderBy('publicacao', 'desc')
        ->limit($request->input('limit'))
        ->skip($request->input('skip'))
    ->get();

    return json_decode($posts);
}

但你可以使用pagination()

中的下一页

答案 1 :(得分:0)

所以,过了一会儿,我想出了一个解决方案来解决我的需求。 结果我不需要json_encode()json_decode()任何事情。

首先,我会对刀片内的所有内容使用伪标记。它很容易理解,因为我使用的是HTML。对于jQuery,参与该项目的人提出了类似伪jQuery的函数来模拟其语法。这是一个直截了当的语法,易于理解,没有任何异常。

然后,就在这里。

PostsController

public function loadMore(Request $request) {
    $limit = $request->input('limit'); 
    $skip = $request->input('skip');
    // as @Dry7 suggested, I am taking a dynamic skip

    $posts = Post::with('categories', 'user', 'media')
        ->where('status', 1)
        ->orderBy('published', 'desc')
        ->limit($limit)
        ->skip($skip)
    ->get();

    return view(
        'portal.pages.blogPost',
        compact(
            'posts'
        )
    )->render(); // here is the difference
}

所以,我所做的是预渲染视图的位置,不加载新页面。

在我们继续之前,这是博客的结构。(使用伪标记,如前所述)

main page

@extends('layouts.layout')

div class=container
    div class=blog
        h1
            Page title
        /h1
        div class=blog-body
            @include('portal.pages.blogPost')

            a id=loadMorePosts class=none 
                Load More
            /a
        /div 

        div class=sidebar
            @include('portal.components.panel')
        /div
    /div   
/div

然后在我的pages.blogPost中,我在我的问题中发布了相同的代码(代码是带有foreach循环的代码。)

在此之后,我想出了类似伪jQuery的代码。

// I'll start listening to any 'click' in the element I am passing the event
// then I'll increment the number of clicks  in the element
var click = 0;

// this is the first skip number
var startCounting = 6;

// start a click event in the <a #loadMorePosts> element 
$.event('#loadMorePosts','click',function () {
        // increment the number of clicks
        click++;

        // set my skip that will be sent to server and
        // applied in my PostsController
        skip = startCounting * click;

        // open an ajax request passing the route I set up
        // that calls PostsController@loadMore method
        HttpRequest.get('{{ route('loadPosts') }}?limit=6&skip=' + skip,function (res) { 
// I am concatenating my skip var here, so It'll be sent to server
            // checking if I have an empty data
            if(res.data != "") {
                // not empty, so I'll append it to my div with blog class
                // first finding the element, searching for its class
                // then passing the data to be appended
                $.append('.blog',res.data);
            } else {
                // the data is empty, so first I'll search for
                // the element with class=none
                // clean up any innerHtml it has
                // then set up a new innerHtml in it
                $.replaceAll('.none',"No More Posts");

                // to finish it all up, I style the same element with some suggesting colors and actions
                $.css('.none', 'pointer-events: none; background-color: lightgrey;');
            }
        });
    });

完成了。帖子被追加,跳过工作,所以我不会重复发帖,它可以工作,直到我的所有帖子都被加载,当没有更多的帖子显示时,按钮被禁用,停止任何新的请求被发送到服务器。

我希望通过这些评论,实现此功能的过程是明确的,您可以对正在使用的任何框架或库应用相同的步骤。

感谢大家阅读和抽出时间回答我的问题。