laravel-admin 【聯動1】二級單向關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;

 

以上是個人分析結果,如有錯誤,敬請執教!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章