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>
  • 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
  • 添加数据到数据库:
    • 在 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');
          }
      }
  • 提示(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();
      }
  • Presenter模式
    • 若将逻辑判断都写在View,会造View肥大而难以维护,我们将使用Presenter模式辅助View,将相关的提示逻辑判断封装到不同Presenter,方便以后维护。
    • 我们以复选框为例:
      1. 首先需要在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>';
                        }
        }
      2. 编写前台代码,如下:
        <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. 由 1 中方法可以看出,我们需要给前台传入数据,所以我们需要在控制器中编写查询数据库数据的代码,然后再传递到前台,下面是控制器中的代码。
          //菜单页面
          public function index(){
                  $menu = $this->menu->findByField('parent_id',0);
                  return view('admin.menu.list')->with(compact('menu'));
          }
      3. 单纯的编写这段代码是不可以的,因为整个控制器是用的仓库模式,在仓库中没有 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();
            }
        1. 完成步骤 4 即可在控制器中查询数据,并返回到前台。

添加菜单-end

本作品采用《CC 协议》,转载必须注明作者和本文链接
老郭博客:laughing: 个人博客地址:www.phpsix.com
PHPSIX
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!