
本文旨在解决在使用 Laravel Eloquent 查询并展示数据后,立即更新数据导致视图刷新问题。我们将探讨几种避免视图在首次加载时被意外刷新的方法,包括使用条件查询、延迟更新以及异步更新等策略,确保用户能够首先看到未更新的数据,然后再进行数据更新。
在 Laravel 开发中,经常需要在展示数据后立即更新数据库。然而,如果在同一个请求中执行查询和更新操作,可能会导致视图在首次加载时显示更新后的数据,这可能不是我们期望的行为。以下是一些解决此问题的方案。
方案一:条件查询
最直接的解决方案是在查询时添加条件,只获取 read_at 为 NULL 的通知。这样,在视图中显示的就是未读的通知,而更新操作则不会影响当前视图。
public function index($showRead = null)
{
$user = auth()->user();
$notifications = $user->notifications()->where('read_at', Null)->orderBy('created_at', 'DESC')->paginate(10);
$view = view('notification.index',['notifications'=>$notifications])->render();
Notification::where('id_user',$user->id)->where('read_at', Null)->update(['read_at'=>now()]);
return $view;
}
登录后复制
注意事项:
- 确保 orderBy(‘created_at’, ‘DESC’) 按照你的实际需求进行排序。
- where(‘read_at’, Null) 是一个常见的陷阱,在某些数据库中可能需要使用 whereNull(‘read_at’)。
方案二:延迟更新
将更新操作延迟到视图渲染之后执行。这可以通过多种方式实现,例如使用 Laravel 的队列。
- 使用 Laravel 队列:
将更新操作放入队列中,在后台异步执行。
use App/Jobs/UpdateNotifications;
public function index($showRead = null)
{
$user = auth()->user();
$notifications = $user->notifications()->latest()->paginate(10);
$view = view('notification.index',['notifications'=>$notifications])->render();
// 将更新操作放入队列
dispatch(new UpdateNotifications($user->id));
return $view;
}
登录后复制
然后创建一个 UpdateNotifications Job:
<?php
namespace App/Jobs;
use Illuminate/Bus/Queueable;
use Illuminate/Contracts/Queue/ShouldBeUnique;
use Illuminate/Contracts/Queue/ShouldQueue;
use Illuminate/Foundation/Bus/Dispatchable;
use Illuminate/Queue/InteractsWithQueue;
use Illuminate/Queue/SerializesModels;
use App/Models/Notification;
class UpdateNotifications implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $userId;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($userId)
{
$this->userId = $userId;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
Notification::where('id_user', $this->userId)->update(['read_at' => now()]);
}
}
登录后复制
注意事项:
- 需要配置 Laravel 的队列系统。
- 确保 Job 中的 Notification 模型的命名空间正确。
方案三:前端异步更新(AJAX)
在视图加载完成后,使用 JavaScript 发送 AJAX 请求来更新通知状态。
- Controller:
public function index($showRead = null)
{
$user = auth()->user();
$notifications = $user->notifications()->latest()->paginate(10);
return view('notification.index',['notifications'=>$notifications]);
}
public function markAsRead()
{
$user = auth()->user();
Notification::where('id_user',$user->id)->update(['read_at'=>now()]);
return response()->json(['success' => true]);
}
登录后复制
- View (Blade):
<script>
window.onload = function() {
fetch('/notifications/mark-as-read', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Notifications marked as read.');
}
});
};
</script>
登录后复制
- Route:
Route::post('/notifications/mark-as-read', [YourController::class, 'markAsRead']);
登录后复制
注意事项:
- 确保在 Blade 模板中包含 CSRF token。
- 根据实际需求调整 AJAX 请求的 URL 和数据。
- 需要引入 fetch API 或者使用 jQuery 的 AJAX 方法。
总结
以上三种方案各有优缺点。条件查询简单直接,但可能会增加数据库的负担。延迟更新可以确保视图的首次加载速度,但需要配置队列系统。前端异步更新可以提供更好的用户体验,但需要编写额外的 JavaScript 代码。选择哪种方案取决于具体的应用场景和需求。在实际开发中,可以根据项目的规模、性能要求以及开发团队的技能水平来选择最合适的方案。
以上就是Laravel Eloquent:如何在显示后更新数据而不影响视图的详细内容,更多请关注php中文网其它相关文章!
相关标签:


