Laravel - 添加菜单
添加菜单 - start#
- 表单构建
- 表单中的 value="{{old ('name')}}" 是调用了 laravel 模版中的一个方法。
当用户提交表单失败后 laravel 会自动把用户的输入数据闪存到一次性的 session 里面(这个数据一刷新就会丢失,故称为一次性数据)。
那么 old ('name') 就可以取出 session 中的闪存数据,从而避让让用户重新输入。<form class="form-horizontal form-label-left" action="{{url('admin/menu')}}" method="post"> {!!csrf_field()!!} <div class="form-group"> <label class="control-label col-md-3 col-sm-3 col-xs-12">菜单名称</label> <div class="col-md-9 col-sm-9 col-xs-12"> <input type="text" class="form-control" name="name" VALUE="{{old('name')}}" placeholder="名称"> </div> </div> </form>
- 表单中的 value="{{old ('name')}}" 是调用了 laravel 模版中的一个方法。
- Request 文件
- 新建 Request 文件:
php artisan make:request MenuRequest
- authorize 方法中默认是 false ,如果为 false 是不会进行验证的,所以要改为 true。
- 在 rules 方法中进行验证:
public function rules() { return [ 'name' => 'required|unique:menus,name', 'parent_id' => 'required', 'url' => 'required', ]; }
- 在 message 方法中添加中文:
public function messages() { return [ 'menu.required' => '菜单名称不能为空!', 'menu.unique' => '菜单名称不能重复!', 'menu.parent_id' => '菜单层级不能为空!', 'menu.url' => '菜单链接不能为空!', ]; }
- 然后在 MenuController 中 use 上面文件:
use App\Http\Requests\MenuRequest;
- 在要验证的方法中注入进入:
public function store(MenuRequest $request) { $result = $this->menu->create($request->all()); //刷新缓存 $this->menu->sortMenuSetCache(); if ($result) { flash('添加菜单成功','success'); }else{ flash('添加菜单失败','error'); } return redirect('admin/menu'); }
- 然后要在前台页面写入下面代码来判断是否有错误验证,如果有,则显示。
@if (count($errors) > 0) <div class="alert alert-danger"> <ul> [@foreach](https://learnku.com/users/5651) ($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif
- 新建 Request 文件:
- 添加数据到数据库:
- 在 Repositories\Eloquent 下新建一个 MenuRepository.php ,在该文件内写如如下代码:
<?php namespace App\Repositories\Eloquent; use App\Repositories\Eloquent\Repository; use App\Models\Menu; class MenuRepository extends Repository{ public function model() { return Menu::class; } }
- 然后在 Repositories\Eloquent 下的 Reopsitory.php 文件下编写创建菜单的方法。
public function create(array $attrributes){ $model = new $this->model; return $model->fill($attrributes)->save(); }
- 该方法中的 fill () 方法是起了过滤的作用,如果要用 fill () 必须要先 new 一个对象,然后还要在 model 中的 $fillable 数组中添加要过滤的字段。下面是 app\Models\Menu.php 文件中的一个私有数组,作用为过滤字段。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; class Menu extends Model{ //过滤字段 protected $fillable = [ 'name', 'icon', 'parent_id', 'url', 'heightlight_url', 'sort', ]; }
- 下面进行对控制器的编写,本控制器中还运用了 flash () 方法,该方法是用于前台的提示功能。
在使用该方法前必须要先在前台相应的位置写入下面一段代码:@include('flash::message')
- 控制器代码:
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Requests; use App\Http\Controllers\Controller; use App\Http\Requests\MenuRequest; use App\Repositories\Eloquent\MenuRepository; class MenuController extends Controller{ private $menu; public function __construct(MenuRepository $menu) { $this->menu = $menu; } //菜单页面 public function index(){ return view('admin.menu.list'); } //添加方法 public function store(MenuRequest $request){ $result = $this->menu->create($request->all()); if ($result){ flash('添加菜单成功','success'); }else{ flash('添加菜单失败','error'); } return redirect('admin/menu'); } }
- 在 Repositories\Eloquent 下新建一个 MenuRepository.php ,在该文件内写如如下代码:
-
提示(flash)的安装:
- 运行 conposer 代码:
composer require laracasts/flash
- 在 config/app.php 文件的 providers 数组中添加下面一行:
'providers' => [ Laracasts\Flash\FlashServiceProvider::class, ];
- 在要使用方法的页面中引入文件:
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
- 然后在控制器中直接使用即可:
public function store(){ flash('Welcome Aboard!'); return home(); }
- 运行 conposer 代码:
- Presenter 模式
- 若将逻辑判断都写在 View,会造 View 肥大而难以维护,我们将使用 Presenter 模式辅助 View,将相关的提示逻辑判断封装到不同 Presenter,方便以后维护。
- 我们以复选框为例:
- 首先需要在 app\Repositories 文件夹下面创建一个名为 Presenter 的文件夹,然后再从 Presenter 文件夹内创建一个名为 MenuPresenter.php 文件,在本文件中编写前台要引入的代码。
<?php namespace App\Repositories\Presenter; class MenuPresenter{ public function getMenu($menus){ if ($menus){ $option = '<option value="0">顶级菜单</option>'; foreach ($menus as $v){ $option .= '<option value="'.$v->id.'">'.$v->name.'</option>'; } return $option; } return '<option value="0">顶级菜单</option>'; } }
- 编写前台代码,如下:
<div class="form-group"> <label class="control-label col-md-3 col-sm-3 col-xs-12">父级菜单</label> <div class="col-md-9 col-sm-9 col-xs-12"> <select class="select2_single form-control" name="parent_id" tabindex="-1"> @inject('menus','App\Repositories\Presenter\MenuPresenter') {!! $menus->getMenu($menu) !!} </select> </div> </div>
- 由 1 中方法可以看出,我们需要给前台传入数据,所以我们需要在控制器中编写查询数据库数据的代码,然后再传递到前台,下面是控制器中的代码。
//菜单页面 public function index(){ $menu = $this->menu->findByField('parent_id',0); return view('admin.menu.list')->with(compact('menu')); }
- 由 1 中方法可以看出,我们需要给前台传入数据,所以我们需要在控制器中编写查询数据库数据的代码,然后再传递到前台,下面是控制器中的代码。
- 单纯的编写这段代码是不可以的,因为整个控制器是用的仓库模式,在仓库中没有 findByField 这个方法,所以不能调用。我们要在 app\Repositories\Eloquent\Repository.php 中编写 findByField () 这个方法,只有这样,才可以在控制器中调用该方法,然后才可以使用。
/* * 根据条件查找数据 * $filed => 要匹配的条件名 * $value => 要匹配的条件值 * $columns => 要查找的条件(*代表所有) */ public function findByField($field,$value,$columns=['*']) { return $this->model->select($columns)->where($field,$value)->get(); }
- 完成步骤 4 即可在控制器中查询数据,并返回到前台。
- 首先需要在 app\Repositories 文件夹下面创建一个名为 Presenter 的文件夹,然后再从 Presenter 文件夹内创建一个名为 MenuPresenter.php 文件,在本文件中编写前台要引入的代码。
添加菜单 - end#
本作品采用《CC 协议》,转载必须注明作者和本文链接
老郭博客
个人博客地址:www.phpsix.com

推荐文章: