首先,官方文档中给出的具体实现方法:
select 联动
select组件支持父子关系的单向联动:
$form->select('province')->options(...)->load('city', '/api/city');
$form->select('city');
其中load('city', '/api/city');的意思是,在当前select的选项切换之后,会把当前选项的值通过参数q, 调用接口/api/city,并把api返回的数据填充为city选择框的选项,其中api /api/city返回的数据格式必须符合:
[
{
"id": 9,
"text": "xxx"
},
{
"id": 21,
"text": "xxx"
},
...
]
控制器action的代码示例如下:
public function city(Request $request)
{
$provinceId = $request->get('q');
return ChinaArea::city()->where('parent_id', $provinceId)->get(['id', DB::raw('name as text')]);
}
坦白讲,看不是太明白
首先,'/api/city' 这个接口文件怎么写? 只说了格式要求,没说具体怎么写,直接创建aip目录,然后添加city类吗?
其次,public function city(Request $request) 这个跟上面的load方法是怎么关联起来的,而且方法内还有个get('q')参数,不理解
网上找了半天,也没找到个能说得清除的,最后没办法,只能硬着头皮看看源码
主要看load()方法
public function load($field, $sourceUrl, $idField = 'id', $textField = 'text', bool $allowClear = true)
{
if (Str::contains($field, '.')) {
$field = $this->formatName($field);
$class = str_replace(['[', ']'], '_', $field);
} else {
$class = $field;
}
$placeholder = json_encode([
'id' => '',
'text' => trans('admin.choose'),
]);
$strAllowClear = var_export($allowClear, true);
$script = <<<EOT
$(document).off('change', "{$this->getElementClassSelector()}"); //移除所有change事件
$(document).on('change', "{$this->getElementClassSelector()}", function () { //添加所有change事件
var target = $(this).closest('.fields-group').find(".$class"); // 从当前元素开始沿 DOM 树向上获取对象
//构造一个GET 请求到sourceUrl页面并取回结果 同时传递q参数,值是当前select选中的option的value值
//这个方法很重要,子类select就是通过这个方法,通过路由找到对应控制器'GoodController@activityList',并获取值的
$.get("$sourceUrl",{q : this.value}, function (data) {
target.find("option").remove();
$(target).select2({
placeholder: $placeholder,
allowClear: $strAllowClear,
data: $.map(data, function (d) {
d.id = d.$idField;
d.text = d.$textField;
return d;
})
}).trigger('change');
});
});
EOT;
Admin::script($script);
return $this;
}
分析:
1、load()方法 有两个参数:
第一个是下级select的name
第二个是获取数据的路由,通过访问该路由到达指定的控制器中,在控制器中获取数据
这里要注意的是load中的路由url不能写错 我这里是 load('subid', '/admin/activityList'); 之前写/activityList一直获取不到数据
protected function form()
{
$form->select('supid', __('大类名称'))->options(
Topcate::all()->where('state','=','1')
->pluck('name','id'))
->load('subid', '/admin/activityList');
$form->select('subid','小类名称');
…………
}
2、添加路由: 在Admin/routes.php 中添加load方法中的路由指向 这里是指定到本控制器中的方法
Route::group([
…………
], function (Router $router) {
…………
$router->get('activityList','GoodController@activityList');
});
3、load()方法中,构造了一个GET请求并带参数q的值,通过路由找到控制器activityList方法,
所以,最后我们要在activityList方法中通过q值获取对应的子类数据
public function activityList(Request $request){
$projectId = $request->get('q');
return Subcate::where('supid',$projectId)->get(['id', DB::raw('name as text')]);
}
最后实现二级联动效果


最后,要注意的是,使用select->load()方法,必须在当前控制器中引入 Request 和 DB类
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
//如果要用到admin JSON组件,还需要引入Admin类
use Encore\Admin\Admin;
以上是个人分析结果,如有错误,敬请执教!
本文详细解析了在web开发中,如何使用Select组件实现父子级联动功能,包括接口编写、路由设置、控制器方法关联及注意事项。

9248

被折叠的 条评论
为什么被折叠?



