【问题标题】:How do I handle an Ajax Response in my Laravel Controller?如何在我的 Laravel 控制器中处理 Ajax 响应?
【发布时间】:2015-03-05 06:39:34
【问题描述】:

我正在使用 Laravel 创建一个社交网站。我正在使用 ajax,因此用户可以在动态数量的帖子上发布 cmets。

我的问题是我不知道如何响应控制器中的 ajax。我的控制台显示 ajax 返回整个页面。这会导致在重新加载页面之前发布的新 cmets 显示不正确。所以我添加了一个if 语句来处理ajax,但我不知道如何处理。

我的 cmets 的 VIEW 看起来像这样。

<div class="comment-box-container ajax-refresh">
// COMMENTS ARE DISPLAYED HERE
  <div class="comment-box">
    @if ($type->comments)
      @foreach ($type->comments as $comment)

        <div class="user-comment-box">

          <div class="user-comment">
            <p class="comment">
<!-- starts off with users name in blue followed by their comment-->
              <span class="tag-user"><a href="{{ route('profile', $comment->owner->id) }}">{{ $comment->owner->first_name }}&nbsp;{{ $comment->owner->last_name }}</a>&nbsp;</span>{{ $comment->body }}
            </p>
<!-- Show when the user posted comments-->
          <div class="com-details">
            <div class="com-time-container">
              &nbsp;{{ $comment->created_at->diffForHumans() }} ·
            </div>
          </div>

        </div><!--user-comment end-->
      </div><!--user-comment-box end-->
    @endforeach
  @endif
// USER TYPES COMMENT HERE
<!--type box-->
  <div class="type-comment">
    <div class="type-box">
    {{ Form::open(['data-remote', 'route' => ['commentPost', $id], 'class' => 'comments_create-form']) }}
        {{ Form::hidden('user_id', $currentUser->id) }}
        {{ Form::hidden($idType, $id) }}
        {{--{{ Form::hidden('user_id', $currentUser->id) }}--}}
        {{ Form::textarea('body', null, ['class' =>'type-box d-light-solid-bg', 'placeholder' => 'Write a comment...', 'rows' => '1']) }}
    {{ Form::close() }}
    </div><!--type-box end-->
  </div><!--type-comment-->

</div><!--comment-box end-->

用户通过按“输入/返回”键提交评论类型框的表单。这是 JS

<script>
    $(document).on('keydown', '.comments_create-form', function(e) {
        if (e.keyCode == 13) {
            e.preventDefault();
            $(this).submit();
        }
    });
</script>

而我的 Ajax 看起来像这样:

(function(){

$(document).on('submit', 'form[data-remote]', function(e){
    e.preventDefault();
    var form = $(this)
    var target = form.closest('div.ajax-refresh');
    var method = form.find('input[name="_method"]').val() || 'POST';
    var url = form.prop('action');

    $.ajax({
        type: method,
        url: url,
        data: form.serialize(),
        success: function(data) {
            var tmp = $('<div>');
            tmp.html(data);
            target.html( tmp.find('.ajax-refresh').html() );
            target.find('.type-box').html( tmp.find('.type-box').html() );
            tmp.destroy();
            }
    });
});
})();

cmets 在 CommentsController 中处理。我的控制器如下所示:

路线

Route::post('post/{id}/comment', ['as' => 'commentPost', 'uses' => 'CommentsController@postComment']);

控制器

public function postComment()
 {
     extract(Input::only('user_id', 'resource_id', 'body'));
     $this->execute(new PostCommentCommand($user_id, $resource_id, $body));
     if(Request::ajax()){
        // NOT SURE WHAT TO PUT HERE???
     }
     return Redirect::back();
 }

我正在使用 Commandbus 。 PostCommentCommand 是一个数据传输对象,最终通过 PostCommentCommandHandler 使用handle() 方法进行处理:

public function handle($command)
{
    $comment = $this->postRepository->leaveComment($command->user_id, $command->resource_id, $command->body);

    return $comment;

}

postRepository-&gt;leaveComment() 看起来像这样:

public function leaveComment($user_id, $resource_id, $body)
{
    $comment = Comment::leavePostComment($resource_id, $body);

    User::findOrFail($user_id)->comments()->save($comment);

    return $comment;
}

我不确定如何在我的控制器中进行这项工作。我知道我需要确定我是否在使用 ajax if(Request::ajax()){},但我不知道之后该怎么做。

我的主要目标是尝试制作一个类似于 facebook 的评论系统。用户可以在任何页面上的任何帖子上进行 cmet,而无需重新加载页面。我希望将同样的 ajax 系统用于“点赞系统”,这样用户就可以在不重新加载页面的情况下点赞照片和 cmets。

有没有人对此有任何想法或解决方案?我是 Laravel 的新手,甚至是 Ajax 和 JavaScript 的新手。详细的描述将不胜感激。谢谢!

【问题讨论】:

    标签: javascript php ajax laravel


    【解决方案1】:

    根据您当前的代码,我将如何完成 ajax 请求:

    1.为单个评论创建comment.blade.php部分视图:

    <div class="user-comment-box">
        <div class="user-comment">
            <p class="comment">
                <span class="tag-user">
                    <a href="{{ route('profile', $comment->owner->id) }}">
                        {{ $comment->owner->first_name }} {{ $comment->owner->last_name }}
                    </a>
                </span>
                {{ $comment->body }}
            </p>
            <div class="com-details">
                <div class="com-time-container">
                    &nbsp;{{ $comment->created_at->diffForHumans() }} ·
                </div>
            </div>
        </div>
    </div>
    

    2.在您的评论foreach循环中包含新评论视图:

    <div class="comment-box-container ajax-refresh">
        <div class="comment-box">
            @if ($type->comments)
                @foreach ($type->comments as $comment)
                    @include('comment')
                @endforeach
            @endif
    
            <div class="type-comment">
                <div class="type-box">
                    {{ Form::open(['data-remote', 'route' => ['commentPost', $id], 'class' => 'comments_create-form']) }}
                        {{ Form::hidden('user_id', $currentUser->id) }}
                        {{ Form::hidden($idType, $id) }}
                        {{--{{ Form::hidden('user_id', $currentUser->id) }}--}}
                        {{ Form::textarea('body', null, ['class' =>'type-box d-light-solid-bg', 'placeholder' => 'Write a comment...', 'rows' => '1']) }}
                    {{ Form::close() }}
                </div>
            </div>
        </div>
    </div>
    

    3.现在在处理 postComment 方法的 ajax 请求时,您应该返回填充了新评论详细信息的 commend.blade.php 视图,如下所示:

    public function postComment()
    {
        extract(Input::only('user_id', 'resource_id', 'body'));
    
        // get the new comment model
        // (also the method here is "dispatch" not "execute")
        $comment = $this->dispatch(new PostCommentCommand($user_id, $resource_id, $body));
    
        if (Request::ajax())
        {
            // return the comment view you created earlier
            // passign the new comment model to it
            return view('comment', compact('comment'));
        }
    
        return Redirect::back();
     }
    

    4. 在您的 JavaScript AJAX 成功回调中,您现在会收到带有新注释的 HTML 响应。您只需将其插入到 cmets 列表的末尾,就在表单之前:

    $.ajax({
        type: method,
        url: url,
        data: form.serialize(),
        success: function(response)
        {
            form.closest('.type-comment').before(response);
        }
    });
    

    就是这样。


    相同的逻辑可以应用于任何其他异步操作,根据每种情况略有不同。例如,要“点赞”一条评论,您需要发送一个 AJAX 请求,然后您可以从服务器回复一个 JSON 响应来指定操作是否成功。 Laravel 部分看起来像这样:

    $liked = like_comment($id); // this is generic
    return response()->json(['success' => $liked]);
    

    在客户端,你会有这样的东西:

    success: function(response)
    {
        if (response.success)
        {
            // update the necessary parts of the page
        }
    }
    

    【讨论】:

    • 感谢您抽空博格丹!我尝试了这个解决方案,但没有出现评论。它已提交到数据库,但没有任何显示。评论也留在类型框中,我可以继续按回车,它会继续发布。直到我重新加载页面,我才在评论框中看到了 cmets。有什么想法吗?
    • AJAX 调用从服务器返回的响应是什么?是comment.blade.php 视图的内容吗?还可以尝试将此行添加到成功回调中,并查看它在浏览器控制台console.log(form.closest('.type-comment')) 中打印出的内容。
    • ah nvm 它说“500 内部服务器错误”,但那是因为我在我的部分中使用了一个变量,我通过了@include('comment', ['deleteRoute' =&gt; 'comDelete])。生病必须想办法解决这个问题。谢谢您的帮助!!我已经被这个卡住了大约 5 天了!
    猜你喜欢
    • 2020-07-27
    • 2021-12-19
    • 2016-12-22
    • 2020-08-06
    • 2017-03-10
    • 2016-01-24
    • 2020-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多