Підготовка даних для Early View за допомогою Laravel View Creators

0
Перекладено ШІ
Оригінал: Laravel News
Оновлено: 17 липня, 2025
Вам цікаво дізнатися, як використовувати Laravel View Creators для покращення управління даними у ваших проєктах? У цій статті ми розглянемо, як правильно впроваджувати View Creators для оптимізації рендерингу ваших шаблонів, створюючи більш ефективні та функціональні додатки

Laravel View Creators виконуються одразу після ініціалізації виглядів, що забезпечує більш ранню точку для впровадження даних у порівнянні з View Composers, сприяючи підготовці критично важливої інформації для процесу рендерингу виглядів.

View Creators відрізняються від View Composers часом виконання: вони запускаються відразу після ініціалізації вигляду, а не тільки перед рендерингом:

use Illuminate\Support\Facades\View;
use App\View\Creators\UserDataCreator;

public function boot()
{
    View::creator('dashboard', UserDataCreator::class);
}

Створіть відповідний клас Creator з підтримкою впровадження залежностей через конструктор.

namespace App\View\Creators;

use App\Services\UserMetricsService;
use Illuminate\View\View;

class UserDataCreator
{
    protected $metricsService;

    public function __construct(UserMetricsService $metricsService)
    {
        $this->metricsService = $metricsService;
    }

    public function create(View $view)
    {
        $view->with('totalUsers', $this->metricsService->getTotalCount());
    }
}

Ось повна система віджетів для бокової панелі, яка демонструє можливості View Creator:

namespace App\View\Creators;

use Illuminate\View\View;
use App\Services\WidgetService;
use App\Services\PermissionService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;

class SidebarCreator
{
    protected $widgetService;
    protected $permissionService;

    public function __construct(WidgetService $widgetService, PermissionService $permissionService)
    {
        $this->widgetService = $widgetService;
        $this->permissionService = $permissionService;
    }

    public function create(View $view)
    {
        $user = Auth::user();

        if (!$user) {
            $view->with('sidebarWidgets', []);
            return;
        }

        $cacheKey = "sidebar_widgets_user_{$user->id}";

        $widgets = Cache::remember($cacheKey, 300, function () use ($user) {
            return $this->buildUserWidgets($user);
        });

        $view->with('sidebarWidgets', $widgets);
        $view->with('widgetPermissions', $this->permissionService->getUserWidgetPermissions($user));
    }

    private function buildUserWidgets($user)
    {
        $availableWidgets = $this->widgetService->getAvailableWidgets();
        $userPreferences = $user->widget_preferences ?? [];

        $widgets = [];

        foreach ($availableWidgets as $widget) {
            if (!$this->permissionService->canAccessWidget($user, $widget['key'])) {
                continue;
            }

            $isEnabled = $userPreferences[$widget['key']]['enabled'] ?? $widget['default_enabled'];
            $position = $userPreferences[$widget['key']]['position'] ?? $widget['default_position'];

            if ($isEnabled) {
                $widgets[] = [
                    'key' => $widget['key'],
                    'title' => $widget['title'],
                    'component' => $widget['component'],
                    'position' => $position,
                    'data' => $this->widgetService->loadWidgetData($widget['key'], $user),
                    'refresh_interval' => $widget['refresh_interval'] ?? 300
                ];
            }
        }

        usort($widgets, fn($a, $b) => $a['position'] <=> $b['position']);

        return $widgets;
    }
}

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        View::creator('layouts.main', SidebarCreator::class);
        View::creator('layouts.dashboard', SidebarCreator::class);
    }
}

class WidgetService
{
    public function getAvailableWidgets()
    {
        return [
            [
                'key' => 'recent_activity',
                'title' => 'Recent Activity',
                'component' => 'widgets.recent-activity',
                'default_enabled' => true,
                'default_position' => 1,
                'refresh_interval' => 60
            ],
            [
                'key' => 'performance_metrics',
                'title' => 'Performance Metrics',
                'component' => 'widgets.performance-metrics',
                'default_enabled' => false,
                'default_position' => 2,
                'refresh_interval' => 300
            ],
            [
                'key' => 'notifications_summary',
                'title' => 'Notifications',
                'component' => 'widgets.notifications-summary',
                'default_enabled' => true,
                'default_position' => 3,
                'refresh_interval' => 30
            ]
        ];
    }

    public function loadWidgetData($widgetKey, $user)
    {
        return match($widgetKey) {
            'recent_activity' => $this->getRecentActivity($user),
            'performance_metrics' => $this->getPerformanceMetrics($user),
            'notifications_summary' => $this->getNotificationsSummary($user),
            default => []
        };
    }

    private function getRecentActivity($user)
    {
        return $user->activities()
            ->latest()
            ->limit(5)
            ->with('subject')
            ->get()
            ->map(fn($activity) => [
                'description' => $activity->description,
                'created_at' => $activity->created_at->diffForHumans(),
                'subject_type' => class_basename($activity->subject_type),
                'icon' => $this->getActivityIcon($activity->description)
            ]);
    }

    private function getPerformanceMetrics($user)
    {
        return [
            'tasks_completed_today' => $user->tasks()->whereDate('completed_at', today())->count(),
            'average_completion_time' => $user->tasks()->avg('completion_time_minutes'),
            'productivity_score' => $this->calculateProductivityScore($user),
            'weekly_trend' => $this->getWeeklyTrend($user)
        ];
    }

    private function getNotificationsSummary($user)
    {
        $unreadCount = $user->unreadNotifications()->count();
        $priorityCount = $user->unreadNotifications()->where('data->priority', 'high')->count();

        return [
            'unread_total' => $unreadCount,
            'high_priority' => $priorityCount,
            'latest_notifications' => $user->notifications()
                ->limit(3)
                ->get()
                ->map(fn($notification) => [
                    'title' => $notification->data['title'] ?? 'Notification',
                    'time' => $notification->created_at->diffForHumans(),
                    'read' => !is_null($notification->read_at)
                ])
        ];
    }
}

View Creators прекрасно підходять для підготовки базових даних, від яких залежить подальша логіка вигляду, оптимізуючи процес рендерингу та забезпечуючи стабільну доступність даних у вашому додатку на Laravel

Популярні

Logomark Logotype

Nuxt 3 + Laravel Sanctum: Просте та надійне рішення для автентифікації вашого SPA та API

У сучасній веб-розробці аутентифікація є ключовою для захисту додатків і даних користувачів. Дізнайтеся, як модуль nuxt-sanctum-authentication спростить інтеграцію між Nuxt 3 та Laravel Sanctum, забезпечуючи надійний і зручний спосіб реалізації аутентифікації для вашого проєкту

Logomark Logotype

4 поширені помилки Vite у Laravel

Використання Vite для створення фронтенд-ресурсів у вашому додатку Laravel може бути захоплюючим, але іноді ви можете стикнутися з певними помилками. У цій статті ми розглянемо чотири поширені помилки, з якими ви можете зіткнутися, а також підкажемо способи їх усунення, щоб ви могли знову зосередитися на розробці вашого додатку

Logomark Logotype

Журнал аудиту в Laravel

Хочете забезпечити повну прозорість у своїх Laravel-додатках? Пакет Laravel Audit Log допоможе вам детально відстежувати всі зміни моделей Eloquent та відповідати вимогам регуляторів. Читайте далі, щоб дізнатися, як цей потужний інструмент може підвищити надійність вашого проєкту