Laravel-admin 創建美觀的樹形無限極分類視圖


版本說明

  • laravel/framework: 5.5.*
  • encore/laravel-admin: ^1.7

表和模型

  • 表結構沒啥好說的,其定義如下:
字段名稱    字段類型    字段描述
id    unsigned int primary key    自增主鍵
pid    unsigned int    父級分類ID
cate_name    varchar(30)    分類名稱
sort    unsigned smallint    排序字段
  • CategoriesModel.php的定義:
<?php
 
 
namespace App\Models;
 
 
use Encore\Admin\Traits\AdminBuilder;
use Encore\Admin\Traits\ModelTree;
use Illuminate\Database\Eloquent\Model;
 
class CategoriesModel extends Model
{
    use ModelTree, AdminBuilder;
    protected $table = 'categories';
 
    protected $fillable = ['pid', 'cate_name', 'sort'];
 
    protected $with = [
        'parent'
    ];
 
 
    public function __construct(array $attributes = [])
    {
        parent::__construct($attributes);
        $this->setParentColumn('pid');  // 父ID
        $this->setOrderColumn('sort'); // 排序
        $this->setTitleColumn('cate_name'); // 標題
    }
 
 
    // 該分類下的品牌
    public function brand()
    {
        return $this->hasMany(BrandModel::class, 'cate_id', $this->getKeyName());
    }
 
 
    /**
     * 該分類的子分類
     */
    public function child()
    {
        return $this->hasMany(get_class($this), 'pid', $this->getKeyName());
    }
 
    /**
     * 該分類的父分類
     */
    public function parent()
    {
        return $this->hasOne(get_class($this), $this->getKeyName(), 'pid');
    }
}

使用了兩個trait: ModelTreeAdminBuilder方便構造樹形結構數據。

需要注意的是在定義表結構時,需要存在parent_id, order, title字段,當然意義上跟其一致即可,名稱可以隨意定義,可以在構造方法中設置對應字段的名稱。

 

控制器定義

  • 通過 php artisan admin:make CategoriesController --model=App\Models\CategoriesModel生成控制器。

    發現CategoriesController是默認繼承AdminController類的,點進去看AdminController類的定義如下:

<?php
 
namespace Encore\Admin\Controllers;
 
use Encore\Admin\Layout\Content;
use Illuminate\Routing\Controller;
 
class AdminController extends Controller
{
    use HasResourceActions;
 
    /**
     * Title for current resource.
     *
     * @var string
     */
    protected $title = 'Title';
 
    /**
     * Set description for following 4 action pages.
     *
     * @var array
     */
    protected $description = [
//        'index'  => 'Index',
//        'show'   => 'Show',
//        'edit'   => 'Edit',
//        'create' => 'Create',
    ];
 
    /**
     * Get content title.
     *
     * @return string
     */
    protected function title()
    {
        return $this->title;
    }
 
    /**
     * Index interface.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function index(Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->description['index'] ?? trans('admin.list'))
            ->body($this->grid());
    }
 
    /**
     * Show interface.
     *
     * @param mixed   $id
     * @param Content $content
     *
     * @return Content
     */
    public function show($id, Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->description['show'] ?? trans('admin.show'))
            ->body($this->detail($id));
    }
 
    /**
     * Edit interface.
     *
     * @param mixed   $id
     * @param Content $content
     *
     * @return Content
     */
    public function edit($id, Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->description['edit'] ?? trans('admin.edit'))
            ->body($this->form()->edit($id));
    }
 
    /**
     * Create interface.
     *
     * @param Content $content
     *
     * @return Content
     */
    public function create(Content $content)
    {
        return $content
            ->title($this->title())
            ->description($this->description['create'] ?? trans('admin.create'))
            ->body($this->form());
    }
}
 
  • AdminController控制器使用了一個trait:HasResourceActions,還有就是對index丶show丶edit丶create操作的封裝。點擊HasResourceActions,看其定義:
trait HasResourceActions
{
    /**
     * Update the specified resource in storage.
     *
     * @param int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function update($id)
    {
        return $this->form()->update($id);
    }
 
    /**
     * Store a newly created resource in storage.
     *
     * @return mixed
     */
    public function store()
    {
        return $this->form()->store();
    }
 
    /**
     * Remove the specified resource from storage.
     *
     * @param int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        return $this->form()->destroy($id);
    }
}

發現Trait:HasResourceActions是對store丶destroy丶update的封裝,類中只有定義了form方法即可實現三種操作。

那么我們的分類控制器:Categories可以通過繼承基本的Controller和使用trait:HasResourceActions來實現樹形圖的操作, CategoriesController.php代碼如下:

<?php
 
namespace App\Admin\Controllers;
 
use App\Models\CategoriesModel;
use Encore\Admin\Controllers\HasResourceActions;
use Encore\Admin\Layout\{Column, Row, Content};
use Encore\Admin\{Tree,Form};
use Encore\Admin\Widgets\Box;
use Illuminate\Http\RedirectResponse;
 
 
/**
 * 分類管理
 * @package App\Admin\Controllers
 */
class CategoriesController extends Content
{
    use HasResourceActions;
 
    protected $title = '分類';
 
    /**
     * 首頁
     * @param Content $content
     * @return Content
     */
    public function index(Content $content)
    {
        return $content->title('分類')
            ->description('列表')
            ->row(function (Row $row){
                // 顯示分類樹狀圖
                $row->column(6, $this->treeView()->render());
 
                $row->column(6, function (Column $column){
                    $form = new \Encore\Admin\Widgets\Form();
                    $form->action(admin_url('categories'));
                    $form->select('pid', __('Parent Category'))->options(CategoriesModel::selectOptions());
                    $form->text('cate_name', __('Category Name'))->required();
                    $form->number('sort', __('Asc Sort'))->default(99)->help('越小越靠前');
                    $form->hidden('_token')->default(csrf_token());
                    $column->append((new Box(__('category.new'), $form))->style('success'));
                });
 
            });
    }
 
 
    /**
     * 樹狀視圖
     * @return Tree
     */
    protected function treeView()
    {
        return  CategoriesModel::tree(function (Tree $tree){
            $tree->disableCreate(); // 關閉新增按鈕
            $tree->branch(function ($branch) {
                return "<strong>{$branch['cate_name']}</strong>"; // 標題添加strong標簽
            });
        });
    }
 
    /**
     * 詳情頁
     * @param $id
     * @return RedirectResponse
     */
    public function show($id)
    {
        return redirect()->route('categories', ['id' => $id]);
    }
 
    /**
     * 編輯
     * @param $id
     * @param Content $content
     * @return Content
     */
    public function edit($id, Content $content)
    {
        return $content->title(__('Categories'))
            ->description(__('edit'))
            ->row($this->form()->edit($id));
    }
 
 
    /**
     * 表單
     * @return Form
     */
    public function form()
    {
        $form = new Form(new CategoriesModel());
 
        $form->display('id', 'ID');
        $form->select('pid', __('Parent Category'))->options(CategoriesModel::selectOptions());
        $form->text('cate_name', __('Category Name'))->required();
        $form->number('sort', __('Asc Sort'))->default(99)->help('越小越靠前');
        return $form;
    }
 
}
 
  • 需要注意的是index方法中的Form和form方法中的form是不同的。
  • CategoriesModel::selectOptions()方法可以快捷的列出可選項包括默認值0。

實現效果圖

  • 首頁(左邊是所有分類,右邊是快捷創建分類。)

 

 

  • 編輯頁

 

 


版權聲明:本文為CSDN博主「ClassmateLin」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/ClassmateLin/article/details/104324581

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM