Laravel 5.6中FullCalendar全局定义calendar_details变量的方法
Undefined variable: calendar_details的问题 你的问题根源在于布局文件layout.app中直接使用了$calendar_details变量,但只有EventsController@index方法传递了这个变量——当切换视图(或访问其他使用该布局的页面)时,这个变量就不存在了,导致报错。下面是两种可靠的全局传递变量的方案,推荐第一种:
方案1:使用View Composers(推荐)
View Composers是Laravel官方推荐的视图数据共享方案,它可以让你指定某个视图(或布局)渲染时自动注入所需数据,逻辑清晰且性能友好。
步骤1:创建Calendar视图Composer类
在app/Http/View/Composers目录下新建CalendarComposer.php(如果目录不存在就手动创建):
<?php namespace App\Http\View\Composers; use Illuminate\View\View; use App\Events; use Calendar; class CalendarComposer { /** * 给视图注入日历数据 */ public function compose(View $view) { // 复用你在EventsController里的日历生成逻辑 $events = Events::get(); $eventList = []; foreach ($events as $event) { $eventList[] = Calendar::event( $event->event_name, true, new \DateTime($event->start_date), new \DateTime($event->end_date) ); } $calendarDetails = Calendar::addEvents($eventList); // 将变量传递给视图 $view->with('calendar_details', $calendarDetails); } }
步骤2:在服务提供者中注册Composer
打开app/Providers/AppServiceProvider.php,在boot方法中注册刚才的Composer,绑定到你的布局视图:
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\View; use App\Http\View\Composers\CalendarComposer; class AppServiceProvider extends ServiceProvider { /** * 启动应用服务 */ public function boot() { // 给layout.app布局绑定Composer,确保所有使用该布局的页面都能拿到变量 View::composer('layout.app', CalendarComposer::class); // 如果需要给所有视图共享这个变量,可以替换成: // View::composer('*', CalendarComposer::class); } /** * 注册应用服务 */ public function register() { // } }
这样一来,每次渲染layout.app布局时,Laravel都会自动调用CalendarComposer生成$calendar_details变量,再也不会出现未定义的错误。
方案2:通过基础控制器全局共享数据
如果你的所有控制器都继承自同一个基础控制器,可以在基础控制器的构造方法中共享变量:
打开app/Http/Controllers/Controller.php(这是默认的基础控制器),修改构造方法:
<?php namespace App\Http\Controllers; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Routing\Controller as BaseController; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use App\Events; use Calendar; class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; public function __construct() { // 生成日历数据并共享给所有视图 $events = Events::get(); $eventList = []; foreach ($events as $event) { $eventList[] = Calendar::event( $event->event_name, true, new \DateTime($event->start_date), new \DateTime($event->end_date) ); } $calendarDetails = Calendar::addEvents($eventList); // 全局共享变量 view()->share('calendar_details', $calendarDetails); } }
这种方法会给所有视图都传递$calendar_details变量,适合所有页面都需要日历数据的场景,但如果只有部分页面需要,方案1更灵活。
额外注意事项
确保你使用的FullCalendar包的Facade已经正确注册到config/app.php的aliases数组中(以maddhatter/laravel-fullcalendar为例):
'aliases' => [ // ... 'Calendar' => MaddHatter\LaravelFullcalendar\Facades\Calendar::class, ],
内容的提问来源于stack exchange,提问作者LightNox

