2025年09月09日/ 浏览 9
在实际Web开发中,我们经常需要处理层级数据的选择与交互。比如电商平台的商品分类系统、多级地区选择器等场景。传统方案通常采用多个独立下拉菜单实现,但这种方式用户体验较差且代码冗余。
Laravel 8提供了更优雅的解决方案:
– 使用Eloquent的hasMany
关系处理嵌套数据
– 配合前端AJAX实现动态加载
– 通过Livewire组件简化交互逻辑
php
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('parent_id')->nullable();
$table->foreign('parent_id')->references('id')->on('categories');
});
php
class Category extends Model
{
public function children()
{
return $this->hasMany(Category::class, ‘parent_id’);
}
public function parent()
{
return $this->belongsTo(Category::class, 'parent_id');
}
}
php
Route::get('/categories', [CategoryController::class, 'index']);
Route::get('/api/categories/{parentId}', [CategoryController::class, 'getChildren']);
php
public function getChildren($parentId = null)
{
return Category::where('parent_id', $parentId)
->get(['id', 'name as text']);
}
html
javascript
$(document).ready(function() {
$(‘#parent-category’).change(function() {
let parentId = $(this).val();
$.get(`/api/categories/${parentId}`, function(data) {
let html = '<div class="form-group mt-3">';
html += '<label>子分类</label>';
html += '<select class="form-control child-category">';
data.forEach(function(category) {
html += `<option value="${category.id}">${category.text}</option>`;
});
html += '</select></div>';
$('#child-categories-container').html(html);
});
});
});
php
public function getChildren($parentId = null)
{
return Cache::remember("categories.{$parentId}", 3600, function() use ($parentId) {
return Category::where('parent_id', $parentId)
->get(['id', 'name as text']);
});
}
通过递归方式处理未知深度的层级结构:javascript
function loadCategorySelect(parentId, container) {
if(parentId) {
$.get(/api/categories/${parentId}
, function(data) {
if(data.length > 0) {
let selectId = ‘category-‘ + Date.now();
let html = <div class="form-group mt-3">
;
<select id="${selectId}" class="form-control child-category">
<option value="">请选择</option>
data.forEach(function(category) {
html += `<option value="${category.id}">${category.text}</option>`;
});
html += '</select></div>';
$(container).append(html);
$('#' + selectId).change(function() {
loadCategorySelect($(this).val(), container);
});
}
});
}
}
php
public function store(Request $request)
{
$validated = $request->validate([
‘selected_category’ => ‘required|exists:categories,id’
]);
// 获取最终选择的分类ID
$categoryId = $request->input('selected_category');
// 业务逻辑处理...
}
javascript
$(‘#submit-btn’).click(function() {
let selectedId = $(‘.child-category:last’).val() || $(‘#parent-category’).val();
$.post('/submit', {
selected_category: selectedId
}, function(response) {
// 处理响应
});
});
with('children')
预加载减少查询次数