在 Laravel 中通过 ajax 加载更雄辩的 hasMany 关系查询?

Posted

技术标签:

【中文标题】在 Laravel 中通过 ajax 加载更雄辩的 hasMany 关系查询?【英文标题】:Loading more eloquent hasMany relation queries through ajax in Laravel? 【发布时间】:2017-12-16 07:39:18 【问题描述】:

在我的网站上,用户可以发布“状态”,其他用户可以回复/评论这些状态。例如,在我网站的首页上,我显示了过去 3 天最喜欢的状态。

在我的 HomeController.php 中:

$statuses = Status::where('is_image', 1)
    ->where('is_mature', 0)
    ->where('created_at', '>=', Carbon::now()->subHours(168))
    ->orderBy('like_count', 'desc')
    ->take(6)
    ->get();

状态也可以有回复。回复使用与状态表相同的表。回复几乎只是具有“父”状态的状态,而常规状态只是没有“父”状态的状态。

来自模型status.php

public function scopeNotReply($query) 
    return $query->whereNull('parent_id');


public function replies() 
    return $this->hasMany('CommendMe\Models\Status', 'parent_id');

回到我的主页,这里是状态在主页上的加载方式:

home.blade.php

@if ($statuses->count())
    @foreach ($statuses as $status)
      <div class="post-container">

        ...

        blah blah blah

        ...

        @foreach ($status->replies->reverse()->slice(0, 3) as $reply)
            <div class="status-reply-content">
                ...

                blah blah blah

                ...
            </div>
        @endforeach

        @if (count($status->replies) > 3)
            <a href="#">
                    View More Comments ( count($status->replies) )
            </a>
        @endif

      </div>
    @endforeach
@endif

我想要的是让“查看更多评论”按钮加载另一组 3 个 cmets。

如果这些是分页的,这将很简单。事实上,在我网站的其他地方,我通过 ajax 加载了更多图像。像这样:

if($request->ajax()) 
    return [
        'images' => view('browse.partials.fullview_partial')->with('images', $images->appends(request()->only('query')))->render(),
        'next_page' => $images->nextPageUrl()
    ];
       

然而,这依赖于通过 ajax 加载下一组分页。而$status-&gt;replies 关系没有被分页。

那么在这种情况下如何加载更多回复?

编辑:

即使是替代解决方案也会有所帮助。

【问题讨论】:

如果状态和回复存储在单独的表中,这似乎会更简单、更合乎逻辑。 这样做的原因是什么?我的意思是,如果没有父级,“回复”永远不会是“状态”,那么为什么要将它们存储在一起呢? 我现在真的不想这样做。那将是最后的手段。 此外,即使我要创建一个回复表,我也不知道如何对回复进行分页,除非你可以在 Laravel 中进行嵌套分页? 【参考方案1】:

您需要在服务器端加载回复的第一页吗?我想既然你愿意用 AJAX 加载后续页面,你可以只处理所有客户端,并且只需要一个提供数据的 AJAX 端点。

只需通过状态 ID 和页码对您的端点进行 ajax 调用。

// AjaxController
public function replies()

    $status = Status::findOrFail(request('id'));
    return $status->replies()->paginate(3);

(页码会自动解析。)

这将返回分页器的 JSON 表示,其中包含上一页和下一页的 url,以及当前页面的数据。然后在客户端渲染数据。

【讨论】:

你的回答和我想的差不多。感谢您的回答!【参考方案2】:

我最终做的只是在我的控制器中为请求本身创建一个新函数,然后将状态 ID 连同它一起发送,以及跳过计数(根据已加载的回复数量而增加) ) 跳过加载的回复。

public function getReplies($statusID, $skip, Request $request) 

    $status = Status::findOrFail($statusID);
    $replies = $status->replies()->orderBy('created_at', 'desc')->skip($skip)->take(10)->get();

    if($request->ajax()) 
        return [
            'replies' => view('templates.partials.replies')->with('replies', $replies)->render(),
        ];
       

【讨论】:

将数据库查询放在if AJAX块内。

以上是关于在 Laravel 中通过 ajax 加载更雄辩的 hasMany 关系查询?的主要内容,如果未能解决你的问题,请参考以下文章

在 laravel 中通过 ajax 返回视图

如何在控制器laravel 8中通过ajax传递路由链接和图像存储链接

在 Laravel 5 中通过 AJAX 将数据从视图发布到控制器

Laravel 雄辩加入 ajax

在 Laravel 5.1 中通过 AJAX 将用户输入数据从视图传递到控制器

在 laravel 中通过 ajax 提交简单的表单,之后,将新行插入到现有表中,其中包含来自提交表单的数据