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 协议》,转载必须注明作者和本文链接
老郭博客:laughing:
个人博客地址:www.phpsix.com
推荐文章: