嵌套回复几乎完成了,只需要将它们排列在视图中

时间:2019-05-29 17:21:53

标签: laravel laravel-5.7

我目前正在Laravel举行一个小型论坛。这将包括(当然)对帖子的评论。我还对评论进行了回复。我通过在Comment模型中添加post_id,commenter_id和parent_id字段来完成此操作。没关系,而且我还做了少量保证金,每个回信都取决于他们的父母。我遇到的麻烦是显示适当的答复,例如:Comment1,然后答复comm.1,然后再对该答复进行另一个答复等等。然后,再对Comment1进行另一个直接答复,对Comment1的第二个直接注释之后的每个后续答复都不会与其他答复分组。如何实现?

这是我要实现的目标的图像: show view with post and it's comments/replies

这是评论模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Post;
use App\User;

class Comment extends Model
{
    protected $fillable = [
        'user_id',
        'post_id',
        'parent_id',
        'body'
    ];

    public function commentPost(){
        return $this->belongsTo("App\Post","post_id");
    }

    public function commentAuthor(){
        return $this->belongsTo("App\User","commenter_id");
    }

    public function replies() {
        return $this->hasMany('App\Comment', 'parent_id');
    }
}

这是展示视图:

@extends("layouts.app")

@section("content")
    <?php 
        /*Pregleda zasebno za title i description da li ima gresaka. 
        Ukoliko ih ima, dodeljume im klasu(crveni border).*/
        $errBody = $errors->has('body') ? 'shake' : '';
    ?>
    <a href="/posts" class="btn btn-outline-info btn-sm">Go Back</a>
    <div style="float:right;">
        <a href="/posts/{{$prev}}" class="btn btn-outline-success"><i class="fas fa-arrow-left"></i></a>
        <a href="/posts/{{$next}}" class="btn btn-outline-info"><i class="fas fa-arrow-right"></i></a>
    </div>
    <h1>{{$post->title}}</h1> 
    <div class="postContainer">
        <img class="postCover" src="/storage/cover_images/{{$post->cover_image}}">

            <div>
            <!--Ovako prikazuje html kod.-->
            <!--{{$post->body}}-->
                {!!$post->body!!}
            </div>

            <small class="timestamp">Written on {{$post->created_at}}</small>
    </div>

    @if(!Auth::guest())
        @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
            <hr>
            <a href="/posts/{{$post->id}}/edit" class="btn btn-outline-primary btn-sm">Edit</a>

            <form action="/posts/{{$post->id}}" method="post" class="float-right">
                @csrf
                {{method_field("DELETE")}}

                <!-- The Modal -->
                <div class="modal" id="myModal">
                    <div class="modal-dialog">
                    <div class="modal-content">

                        <!-- Modal Header -->
                        <div class="modal-header">
                        <h4 class="modal-title">Are yoy sure you want to delete this post?</h4>
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                        </div>

                        <!-- Modal body -->
                        <div class="modal-body">
                            <button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
                        </div>

                        <!-- Modal footer -->
                        <div class="modal-footer">
                        <button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
                        </div>

                    </div>
                    </div>
                </div>

            </form>

            <button class="btn btn-outline-danger btn-sm float-right" data-toggle="modal" data-target="#myModal">Delete</button>
        @endif
    @endif

    @auth
    <hr>

    @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
        <form method="POST" action="/posts/{{$post->id}}/comments">
            @csrf
            <!-- https://laravel.com/docs/5.7/validation#available-validation-rules -->

            <div class="form-group animated {{$errBody}}">
                <textarea id="ckeditor" class="form-control" name="body" placeholder="Post body" required value=""></textarea>
            </div>

            <div>
                <button type="submit" class="btn btn-outline-success btn-sm">Post comment</button>
            </div>

        </form>
    @endif

    <hr>
    @endauth
    <h6 style="border-bottom: 1px solid whitesmoke;">Comments <span class="badge" style="background-color: whitesmoke; border: 1px solid silver;vertical-align: top;">{{count($comments)}}</span></h6>
    <div class="container commContainer">

        <ul class="list-group" style="list-style-type:none">
            @if(count($comments) > 0)
                @foreach ($comments as $index => $comment)

                    <li>

                        @if($index>0)
                            <div class="horDiv"></div>
                        @endif

                        {{$comment->commentAuthor->name}} has said parent_id: {{$comment->parent_id}}
                    </li>
                    <li class="list-group-item py-2 commBody" style="margin-left: calc({{$comment->parent_id}}*10px) !important" parent_id="{{$comment->parent_id}}" id="{{$comment->id}}">My id: {{$comment->id}} {!!$comment->body!!} 
                        @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)
                            <br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $comment->id }}')";>reply</span>
                            @include('inc.replyForm')
                        @endif
                    </li>

                @endforeach

            @endif

        </ul>

    </div>

@endsection

我只是猜测,但是可以通过视图本身来完成吗?我尝试在控制器将其传递给视图之前进行分组和排序,但是没有任何效果。我赞赏正确方向上的每一点。

编辑: 这是CommentsController中的存储方法。

public function store(Request $request, $id)
    {
        $this->validate($request, [
            "body" => "required"

        ]);

        $data = array(
            "body" => $request->input("body"),
            "post_id" => intval($id),
            "commenter_id" => Auth::user()->id,
            "imParent_id" => $request->input("comment_id")
        );
        //dd($data);
        $comment = new Comment;
        $comment->body = $data["body"];
        $comment->post_id = $data["post_id"];
        $comment->commenter_id = $data["commenter_id"];
        $comment->parent_id = $data["imParent_id"];

        $comment->save();

        $post = Post::find($id);
        $comments = $post->comments;
        //return redirect("/posts/{{$id}}")->with("success", "Post Created")->with('comments', $comments);
        //return view("posts.show")->with(compact('post', 'comments'));
        //with(['replies' => function($comments){ $comments->orderBy('parent_id') } ])
        return back()->with('comments', $comments);
    }

编辑2:

这是PostController中的show方法:

public function show($id)
    {

        $post = Post::find($id);  

        $comments = $post->comments;

        $prev = $post->prev($post);
        $next = $post->next($post);

        return view("posts.show")->with(compact("post", "prev", "next", "comments"));
    }

Edit3:

这是相当有缺陷的尝试(在显示视图中):

@if(count($comments) > 0)

                @for($i=0;$i<count($comments);$i++)

                    @if(!$comments[$i]->parent_id)
                        <li class="list-group-item py-2 commBody" parent_id="{{$comments[$i]->parent_id}}" id="{{$comments[$i]->id}}">
                            {!!$comments[$i]->body!!}
                        </li>
                        @for($k=0;$k<count($comments);$k++)

                            @if($comments[$i]->id==$comments[$k]->parent_id)
                            <?php array_push($myArray,$comments[$i]->id); ?>
                                <li class="list-group-item py-2 commBody" style="margin-left: calc({{$comments[$k]->parent_id}}*10px) !important" parent_id="{{$comments[$k]->parent_id}}" id="{{$comments[$k]->id}}">
                                    {!!$comments[$k]->body!!}
                                </li>
                            @endif

                        @endfor
                        {{"///////////////////////////////////////////////"}}
                    @endif

                    @if(array_search($comments[$i]->parent_id,$myArray)===false)


                        @for($k=0;$k<count($comments);$k++)

                            @if($comments[$i]->id==$comments[$k]->parent_id)


                            <li class="list-group-item py-2 commBody" style="margin-left: calc({{$comments[$k]->parent_id}}*10px) !important" parent_id="{{$comments[$k]->parent_id}}" id="{{$comments[$k]->id}}">
                                {!!$comments[$k]->body!!}
                            </li>

                            @endif

                        @endfor

                    @endif

                @endfor
@endif

及其与重复项的外观:

duplicates

Edit4:

按照蒂姆·刘易斯的建议,将注释(无父母)与答复(与父母)分开,这是显示它们并发送附加参数以部分答复的方式:

<ul class="list-group" style="list-style-type:none">
            @if(count($comms) > 0)

                @for($i=0;$i<count($comms);$i++)

                    <li class="list-group-item py-2 commBody" style="margin-left: calc({{"0"}}*10px) !important" parent_id="{{$comms[$i]->parent_id}}" id="{{$comms[$i]->id}}">

                        {{$comms[$i]->body}}

                        @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)

                            <br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $comms[$i]->id }}')";>reply</span>
                            @include('inc.replyForm', array('par' => $comms[$i]))

                        @endif

                    </li>

                    <li>@if($i>0) <div class="horDiv"></div> @endif </li>

                    @if(count($replies) > 0)

                        @for($j=0;$j<count($replies);$j++)

                            @if($comms[$i]->id==$replies[$j]->parent_id)
                                <li class="list-group-item py-2 commBody" style="margin-left: calc({{$comms[$i]->id}}*10px) !important" parent_id="{{$replies[$j]->parent_id}}" id="{{$replies[$j]->id}}">

                                    {{$replies[$j]->body}}

                                    @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)

                                        <br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $replies[$j]->id }}')";>reply</span>
                                        @include('inc.replyForm', array('par' => $replies[$j]))

                                    @endif

                                </li>
                                <li>@if($j>0) <div class="horDiv"></div> @endif </li>
                            @endif

                            @for($k=$j;$k<count($replies);$k++)

                                @if($replies[$k]->parent_id==$replies[$j]->id)
                                    <li class="list-group-item py-2 commBody" style="margin-left: calc({{$replies[$j]->id}}*10px) !important" parent_id="{{$replies[$k]->parent_id}}" id="{{$replies[$k]->id}}">

                                        {{$replies[$k]->body}}

                                        @if(Auth::check() && Auth::user()->role_id<3 && Auth::user()->role_id>0)

                                            <br><span class="btn btn-outline-primary btn-sm" style="width: 40px;height: 20px;line-height: 5px;padding: 5px;" onclick="reply('reply{{ $replies[$k]->id }}')";>reply</span>
                                            @include('inc.replyForm', array('par' => $replies[$k]))

                                        @endif

                                    </li>
                                    <li>@if($k>0) <div class="horDiv"></div> @endif </li>
                                @endif

                            @endfor

                        @endfor

                    @endif

                @endfor

            @endif
        </ul>

1 个答案:

答案 0 :(得分:0)

我之前曾经做过分类。提示:

<select name="category_id" class="form-control chosen-select" required value="{{ old('category_id') }}">
            @foreach(App\Category::where('parent_id',0)->get() as $c)
                <option value="{{$c->id}}">*{{$c->name}}</option>
                @foreach(App\Category::where('parent_id',$c->id)->get() as $d1)
                    <option value="{{$d1->id}}"> - {{$d1->name}}</option>
                @endforeach
            @endforeach
        </select>