如何在Laravel控制器使用Inner Join并传结果至Blade模板实现点击显示对应课时
Laravel实现点击课程标题显示对应课时
咱们先梳理下现有代码里的小问题,再一步步调整实现需求:
一、修正控制器代码
你原来的控制器存在几个明显问题:$courses变量未定义、只查询了课时的long_text字段却没获取课程标题、视图名称没加引号,而且查询逻辑应该从课程表关联课时表,这样才能拿到每个课程对应的课时内容。调整后的代码如下:
public function index() { // 关联courses和lessons表,获取课程ID、标题以及对应的课时内容 $courses = DB::table('courses') ->join('lessons', 'courses.lesson_id', '=', 'lessons.id') ->select('courses.id', 'courses.title', 'lessons.long_text as lesson_content') ->get(); // 把查询到的课程集合传递给视图 return view('lesson.index', compact('courses')); }
二、改造Blade模板实现点击显示
现在需要在模板里遍历所有课程,给每个标题添加点击交互,点击后显示对应的课时内容。这里提供两种简单的实现方式:
方式1:使用HTML原生<details>标签(无需JS)
这个方式最简洁,利用HTML自带的折叠展开功能:
<ul> @foreach($courses as $course) <li style="text-transform: uppercase; margin: 10px 0;"> <details> <!-- 点击标题即可展开/折叠课时内容 --> <summary>{{ $course->title }}</summary> <div style="margin-top: 8px; padding-left: 15px;"> {{ $course->lesson_content }} </div> </details> </li> @endforeach </ul>
方式2:使用JavaScript控制显示隐藏(更灵活)
如果需要自定义动画或样式,可以用JS手动控制:
<ul> @foreach($courses as $course) <li style="text-transform: uppercase; margin: 10px 0;"> <!-- 给标题添加点击触发样式 --> <span class="course-title" style="cursor: pointer; color: #007bff;">{{ $course->title }}</span> <!-- 默认隐藏课时内容 --> <div class="lesson-content" id="lesson-{{ $course->id }}" style="display: none; margin-top: 8px; padding-left: 15px;"> {{ $course->lesson_content }} </div> </li> @endforeach </ul> <script> // 给所有课程标题绑定点击事件 document.querySelectorAll('.course-title').forEach(titleElement => { titleElement.addEventListener('click', function() { const lessonContent = this.nextElementSibling; // 切换显示/隐藏状态 lessonContent.style.display = lessonContent.style.display === 'none' ? 'block' : 'none'; }); }); </script>
补充说明
如果你的课程和课时是一对多关系(一个课程对应多个课时),那需要调整查询逻辑,比如使用Eloquent关联(在Course模型里定义hasMany(Lesson::class)),这样就能拿到每个课程的所有课时列表,而不是单个课时内容。
内容的提问来源于stack exchange,提问作者user9588053
相关产品推荐
相关产品推荐

