laravel-admin 【联动1】二级单向关select联菜单实现

本文详细解析了在web开发中,如何使用Select组件实现父子级联动功能,包括接口编写、路由设置、控制器方法关联及注意事项。

首先,官方文档中给出的具体实现方法:

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;

 

以上是个人分析结果,如有错误,敬请执教!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值