使用laravel一分鐘搭建CURD後臺頁面

配置即一切

一切皆於需求,後臺從0開始搭建,可是寫了一兩個頁面後發現太多的是對單表的增刪改查操做,因而就想到了,能不能作一個快速搭建的後臺。想到一句話,配置即一切。若是一個CURD後臺能只進行配置就自動生成,該是多麼美妙的事情,那麼就開始搭建這麼個結構。
 

首先配置文件應該怎麼設計

起初想到將配置文件放到config目錄下,可是想一想仍是放棄了這個想法,那樣子可能會致使有一個「萬能」文件,又臭又長。那麼,其次,這個功能只針對單表,因此,是否是能夠將配置文件放置在Model中,後來也以爲這個想法不大好,這個配置文件是承擔頁面展現的功能的,若是放在Model中就算是入侵了Model層了。因此最後決定放在了Controller中。
 

最後的效果大概是什麼樣子的?

後臺大概會有幾個頁面:

列表頁:

列表頁中有查詢操做,編輯,刪除按鈕,新建按鈕。

新建頁面:

 

編輯頁面:

 
好了,對應這幾個頁面,咱們能夠設置配置項了。
 
基本想法是搭建一個FormController,全部之後須要配置生成後臺的controller就繼承這個FormController就行了。在FormController中定義屬性:
class FormController extends BaseController {
 
     // 對應的模型
     protected $model;
 
     // 全部的字段
     protected $fields_all;
 
     // 列表頁顯示的字段
     protected $fields_show;
 
     // 編輯頁面顯示的字段
     protected $fields_edit;
 
     // 建立頁面顯示的字段
     protected $fields_create;
}
定義了Model,來表示這個Controller是對那個Model進行單表操做的。
定義了fields_all屬性,來將全部的字段來進行一個說明和定義。這個定義和說明就包括字段顯示名字,字段是否要進行搜索,字段類型是什麼。
對於列表頁,不是全部屬性都顯示出來,因此定義一個$fields_show,這個數組存放的是$fields_all中的一些字段,用來顯示的字段。
對於編輯頁面,要顯示的字段就放在$field_edit中
對於建立頁面,要顯示的字段就放在$field_create中
 
好了,如今繼承FormController的類就只須要這麼配置就好;
<?php
 
// 帳號管理系統
class BadminController extends FormController
{
 
     public function __construct()
     {
          $this->model = '\Badmin';
          $this->fields_all = [
               'id' => [
                    'show' => '序號',
               ],
               'nickname' => [
                    'show' => '暱稱',
                    'search' => "nickname like CONCAT('%', ?, '%')"
               ],
               'username' => [
                    'show' => '用戶名',
               ],
               'email' => [
                    'show' => '郵箱',
               ],
               'password' => [
                    'show' => '密碼',
               ],
               'created_at' => [
                    'show' => '建立時間',
               ],
               'updated_at' => [
                    'show' => '更新時間',
               ],
          ];
 
          $this->fields_show = ['id' ,'nickname', 'username', 'email', 'created_at'];
          $this->fields_edit = ['nickname', 'username'];
          $this->fields_create = ['nickname', 'username', 'email', 'password'];
          parent::__construct();
     }
} 
在構造函數中定義model,$fields_all, $fields_show, $fields_edit, $fields_create。
對於fields_all,key爲數據庫對應的字段名,value爲一個數組,show是顯示名,若是你在列表頁但願這個字段能進行搜索,就設置下search屬性。
 

路由

下面是路由,laravel中路由基本有三種:
Route::get('order/{id}',['as'=>'order.detail','uses'=>'OrderController@show']);
Route::controller('preview', 'PreviewController');
Route::resource('badmin', 'BadminController');

 

第三種已經徹底定義好了增刪改查操做,看起來能省我很多的事情,好吧,我就使用這個resource來作了。
 
因此在route.php中我只須要定義這麼一條就ok了
 
// 管理員帳號管理
Route::resource('badmin', 'BadminController');

 

Controller 

下面寫FromController中的resource方法
 
按照laravel的resource定義的,須要填充的方法有:
 
我習慣在構造函數中把一些諸如Input,全局定義的東西都share到模版中,代碼以下:
     public function __construct()
     {
 
          // TODO:作一些基礎的判斷,若是沒有的話就拋出異常
         
          $route = Route::currentRouteAction();
          list($this->controller, $action) = explode('@', $route);
          View::share('controller', $this->controller);
 
          $fields_show = array();
          foreach ($this->fields_show as $field) {
               $fields_show[$field] = $this->fields_all[$field];
          }
          View::share('fields_show', $fields_show);
 
          $fields_edit = array();
          foreach ($this->fields_edit as $field) {
               $fields_edit[$field] = $this->fields_all[$field];
          }
          View::share('fields_edit', $fields_edit);
 
          $fields_create = array();
          foreach ($this->fields_create as $field) {
               $fields_create[$field] = $this->fields_all[$field];
          }
          View::share('fields_create', $fields_create);
 
          View::share('input', Input::all());
     }

 

這裏把controller放到外面是爲了在view中可使用諸如:
action($controller . '@destroy', $model->id),
的路徑定義
 
index函數:
 
 
     public function index()
     {
          $model = new $this->model;
          $builder = $model->orderBy('id', 'desc');
 
          $input = Input::all();
          foreach ($input as $field => $value) {
               if (empty($value)) {
                    continue;
               }
               if (!isset($this->fields_all[$field])) {
                    continue;
               }
               $search = $this->fields_all[$field];
               $builder->whereRaw($search['search'], [$value]);
          }
          $models = $builder->paginate(20);
 
          return View::make('form.index', [
               'models' => $models,
          ]);
     }
 

$builder在laravel中真是太TMD好用了,對於這裏的搜索,我使用whereRaw進行prepare查詢。這裏還有一個點,以前在fields_all設計的時候,我定義的直接是一個 'search' => "nickname like CONCAT('%', ?, '%')"  這裏定義搜索字段的時候其實有不少種設計方法,好比定義爲php

‘search’ => [
     'type' => 'like',
     'value' => '%?%'
]

 

 
可是考慮到使用這個FromController的都是程序員,因此這裏的search直接使用預處理的語句,而後在index中直接使用whereRaw,這樣使得配置文件的易讀性增長了。
 
下面是

create函數:

     public function create()
     {
          return View::make('form.create', []);
     }
 

 

store函數:

     public function store()
     {
          $model = new $this->model;
          $model->fill(Input::all());
          $model->save();
          return Redirect::to(action($this->controller . '@index'));
     }
 

 

這裏的model的fill是否是很簡單,爽到爆。固然model中仍是須要定義fillable字段
 

edit,update,destory函數

如法炮製就好
 
     public function edit($id)
     {
          $model = new $this->model;
          $model = $model->find($id);
          return View::make('form.edit', compact('model'));
     }
 
     public function update($id)
     {
          $model = new $this->model;
          $model = $model->find($id);
          $model->fill(Input::all());
          $model->save();
 
          return Redirect::to(action($this->controller . '@index'));
     }
 
     public function destroy($id)
     {
          $model = new $this->model;
          $model->destroy($id);
         
          return Redirect::to(action($this->controller . '@index'));
     }
 

 

 View

下面就是view的編寫。
view大概就只要三個頁面,列表頁面,編輯頁面,建立頁面
 

列表頁面注意事項:

1 使用laravel自帶分頁,注意記得帶上本頁的輸入參數,這個時候,構造函數中share的Input就頗有用了

{{$models->appends($input)->links()}}
 

2 可使用laravel自帶的from操做,好比刪除操做因爲須要調用HTTP的DELETE 方法,能夠這麼寫

                 {{ Form::open(array(
                  'id' => "delete_{$model->id}",
                  'url' => action($controller . '@destroy', $model->id),
                  'class' => 'dropdown-toggle')) }}
                    {{ Form::hidden('_method', 'DELETE') }}
                  {{ Form::close() }}

 

 
其實本身寫DELETE也行,就是在From表單中多傳遞一個_method隱藏域
 

3 搜索直接使用一個form就能夠搞定了

     <form class="form-inline" role="form" action="{{action($controller . '@index')}}">
          @foreach ($fields_show as $field => $field_info)
            @if (isset($field_info['search']))
            <div class="form-group">
              <label class="col-sm-3 control-label">{{$field_info['show']}}</label>
              <div class="col-md-3">
                <input name="{{$field}}" type="input" class="form-control" placeholder="" value="@if (isset($input[$field])){{$input[$field]}}@endif">
              </div>
            </div>
            @endif
          @endforeach
          <input type="submit" class="btn btn-success" value="查詢" />
        </form>

 

編輯頁面和建立頁面

簡單到只須要一個form就能搞定了
 
  <form class="form-horizontal"
          role="form"
          action="{{action($controller . "@update", $model->id)}}" method='POST'>
          <input type="hidden" name="_method" value="PUT">
            @foreach ($fields_edit as $field => $field_info)
            <div class="form-group">
              <label class="col-sm-2 control-label">{{$field_info['show']}}</label>
              <div class="col-sm-10">
                <input name="{{$field}}" type="text" class="form-control" placeholder="" value="{{$model->$field}}">
              </div>
            </div>
            <div class="line line-dashed line-lg pull-in"></div>
            @endforeach
            <div class="col-sm-4 col-sm-offset-2">
              <button type="submit" class="btn btn-primary">提交</button>
            </div>
          </form>

 

 
記得resource中更新的操做是要使用PUT方式,刪除的操做要使用DELETE方式。
至於view的模版,我這裏使用的是一款叫notebook的模版,它是基於bootstrap的,你也可使用其餘更好看的模版來寫。
 
好了,至此這麼個快速搭建CURD的結構就完成了。如今能夠在運營人員給需求的時候,很牛逼地說,等我一分鐘,我就給你一個世界~~

後記

其實回想下,這整個結構不算複雜。配置即一切的思想能解決不少問題。可是依賴配置的路子最怕的是幾個事情:
1 配置文件過於複雜。(若是你的配置文件過於複雜,已經超過了敲代碼自己須要瞭解的東西,那麼這個配置項的學習成本就太太過高了)
2 配置字段語意不清。(配置的字段名字和意思不對,字段名和變量名同樣重要!)
 
固然這個就是個初步,改進的幾個點還有
1 全部字段都使用input標籤,須要在配置中加入其它標籤類型
2 是否是考慮view中全部的東西都使用laravel自帶的form對應字段?
相關文章
相關標籤/搜索