【问题标题】:Laravel Eloquent update after displayLaravel Eloquent 显示后更新
【发布时间】:2021-12-28 12:06:37
【问题描述】:

我在使用自定义通知模型(不是 Laravel 标准模型)时遇到了问题。

在我的控制器中,我获取所有通知并将它们保存到一个变量中。

之后,我将更新所有通知并设置 read_at 日期时间。

    public function index($showRead = null)
    {
        $user = auth()->user();
        $notifications = $user->notifications()->latest()->paginate(10);
        $view = view('notification.index',['notifications'=>$notifications])->render();
        Notification::where('id_user',$user->id)->update(['read_at'=>now()]);
        return $view;
    }

问题:

$notifications 集合确实包含 read_at NULL 条目,因为我在第二行获取数据。

但不知何故,更新也会刷新渲染视图。

我能以某种方式阻止这种情况吗?我想在第一页请求上显示未读通知,在下面的请求中,它们应该有时间戳。

【问题讨论】:

  • 可以分享一下视图刀片文件吗?

标签: php laravel eloquent laravel-blade


【解决方案1】:

在此查询中使用where() 条件来获取未读通知:$notifications = $user->notifications()->where('read_at', Null)->orderBy('created_at', 'DESC')->paginate(10);


阅读后更新通知的解决方案:

解决方案 1:

将未读通知存储到Laravel Collections 并压缩到视图:$notifications = $user->notifications()->latest()->paginate(10);

解决方案 2:

或者在您的视图刀片中运行此查询Notification::where('id_user',$user->id)->update(['read_at'=>now()]);

解决方案 3:

当用户将访问通知视图刀片时,发送 AJax 请求以更新通知。

【讨论】:

    【解决方案2】:

    您可以在通知上创建一个构建器(不要使用 get),然后将第一个构建器克隆到另一个变量中,之后您可以更新克隆的构建器并从原始构建器获取集合。

    $notifsBuilder1= $user->notifications();
    $notifsBuilder2 = clone $notifsBuilder1;
    $notifs = $notifsBuilder1->latest()->paginate(10);
    $notifsBuilder2->update(['read_at'=>now()])
    

    【讨论】:

      【解决方案3】:

      进行此类操作的最简单方法是让您的前端向您的控制器发送一个 api 请求以读取某个通知。 你可以这样做:

      
      class NotificationsController extends Controller{
        public function index(Request $request, $showRead = null){
          $user = auth()->user();
          $notifications = Notification::where('user_id', $user->getKey())->latest()->orderBy('created_at')->paginate(10);
          return view('notifications.index', compact('notifications'));
        }
      
        public function markAsRead(Notification $notification){
          $done = $notification->forceFill(['read_at' => now()]);
          return compact('done');
        }
      }
      
      
      

      如果您使用的是 VueJs,那么您可以在前端内部使用它(不用担心,您也可以查找匹配的东西,如果不是):

      在你的 Vue 组件内部使用 axios 库来处理请求,并为你的路由使用 ziggy 库:

      
      let axios = require('axios');
      let notifications = [];
      let getNotifications = async () => {
        return axios.get(route('notifications.index')).then(res => {
          notifications = res.data.notifications;
        });
      }
      let markNotificationAsRead = (notification_id) => {
        axios.get(route('notification.read', ['notification' => notification_id]));
      }
      
      getNotifications();
      for(let i = 0; i < notifications.length; i++){
        markNotificationAsRead(notifications[notification].id);
      }
      
      

      这样,您的所有通知都是通过您的 api 和您的 api 处理的,因为成像您的用户会要求通知,但在您将他的响应交给他之前取消了请求,他实际上会错过这些。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-19
        • 2017-05-10
        • 1970-01-01
        • 2013-09-21
        • 2016-04-19
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        相关资源
        最近更新 更多