Laravel Dcat-admin 详情页多栏布局开发

举报
Lansonli 发表于 2021/09/29 00:21:53 2021/09/29
【摘要】 背景 随着 dcat-admin 越来越多的人使用,相信有许多跟我一样热爱这个项目的的人最后也会参与到这个项目中来,从使用者到项目的维护者,可以为项目贡献一份自己的力量。我以后也会将维护这个项目的一些心得,底层代码的实现都以博文的形式分享给大家。 需求 有个同学提了一个这样的需求 ; 需要在表单 / 详情支持多栏布局,而这个需...

背景


随着 dcat-admin 越来越多的人使用,相信有许多跟我一样热爱这个项目的的人最后也会参与到这个项目中来,从使用者到项目的维护者,可以为项目贡献一份自己的力量。我以后也会将维护这个项目的一些心得,底层代码的实现都以博文的形式分享给大家。

需求


有个同学提了一个这样的需求 ; 需要在表单 / 详情支持多栏布局,而这个需求刚好我自己用 dcat-admin 做项目时候也遇到过。尤其是 form 表单字段比较多的时候,我开始的解决方案是通过 form 的 tab 来减少表单一页的字段数量。

表单的多栏目布局
思路:我想的是 form 表单的字段外面包一次 row ,然后控制 row 里面每个字段的长宽。当我看了 dcat-admin 的代码后,发现是已经实现好了的,所以不需要自己在开发,我这里主要讲讲表单的多栏目布局的用法和底层代码怎么实现的。
效果:


使用代码:

在控制器创建一个 from 方法


  
  1. protected function form()
  2.   {
  3.       return Form::make(new WxyMaterialItem(), function (Form $form) {
  4.           $form->row(function (Form\Row $row) {
  5.               $row->width(4)->text('name')->required();
  6.               $row->width(4)->text('id');
  7.               $row->width(4)->text('simple_code');
  8.           });
  9.           $form->row(function (Form\Row $row) {
  10.               $row->width(6)->text('integral_money');
  11.               $row->width(6)->text('stock_min');
  12.           });
  13.           $form->row(function (Form\Row $row) {
  14.               $row->width(12)->text('attribute');
  15.           });
  16.           $form->row(function (Form\Row $row) {
  17.               $row->width(3)->text('price1');
  18.               $row->width(3)->text('price2');
  19.               $row->width(3)->text('price3');
  20.               $row->width(3)->text('status');
  21.           });
  22.       });
  23.   }


代码分析:

整个 form 表单渲染出来的流程如下
Dcat\Admin\Form 对象 -> 方法 rows 实例化一个 Dcat\Admin\Form\Row 对象并保存对象属性 -> 最后通过 render 方法渲染界面

这里面核心作用文件是 Dcat\Admin\Form\Row,我们可以看看里面的几个方法

width 方法


  
  1. public function width($width = 12)
  2.   {
  3.       $this->defaultFieldWidth = $width;
  4.       return $this;
  5.   }


这个方法主要设置当前行的每一个显示字段的宽度,比如你一行显示三个字段
建议每个字段的宽度设置为 3,例如 $row->width (3)->text (‘name’);

__call 方法


  
  1. public function __call($method, $arguments)
  2.   {
  3.       $field = $this->form->__call($method, $arguments);
  4.       $field->disableHorizontal();
  5.       $this->fields[] = [
  6.           'width'   => $this->defaultFieldWidth,
  7.           'element' => $field,
  8.       ];
  9.       return $field;
  10.   }


这个方法主要是保存当前行要显示的字段的信息,通过 __call 方法去调用 Dcat\Admin\Form 的字段方法获取字段信息,如使用代码的 $row->width (4)->text (‘name’),会保存一个宽度 col-md-4 的 Dcat\Admin\Form\Field\Text 字段。

render 方法


  
  1.   public function render()
  2.   {
  3.       return view('admin::form.row', ['fields' => $this->fields]);
  4.   }


admin::form.row 视图


  
  1. <div class="row">
  2.   @foreach($fields as $field)
  3.   <div class="col-md-{{ $field['width'] }}">
  4.       {!! $field['element']->render() !!}
  5.   </div>
  6.   @endforeach
  7. </div>

$field [‘element’]->render () 就是将字段渲染成 html
我们可以 dd 下 $this->fields , 看看其数据结构


详情的多栏目布局
思路:详情的多栏目布局是需要重新开发的,思路逻辑是和表单的多栏目布局类似的
主要是创建一个 Dcat\Admin\Show\Row 文件,里面的代码如下


  
  1. <?php
  2. namespace Dcat\Admin\Show;
  3. use Dcat\Admin\Show;
  4. use Illuminate\Contracts\Support\Renderable;
  5. use Illuminate\Support\Collection;
  6. class Row implements Renderable
  7. {
  8.     /**
  9.      * Callback for add field to current row.s.
  10.      *
  11.      * @var \Closure
  12.      */
  13.     protected $callback;
  14.     /**
  15.      * Parent show.
  16.      *
  17.      * @var Show
  18.      */
  19.     protected $show;
  20.     /**
  21.      * @var Collection
  22.      */
  23.     protected $fields;
  24.     /**
  25.      * Default field width for appended field.
  26.      *
  27.      * @var int
  28.      */
  29.     protected $defaultFieldWidth = 12;
  30.     /**
  31.      * Row constructor.
  32.      *
  33.      * @param \Closure $callback
  34.      * @param Show $show
  35.      */
  36.     public function __construct(\Closure $callback, Show $show)
  37.     {
  38.         $this->callback = $callback;
  39.         $this->show = $show;
  40.         $this->fields = new Collection();
  41.         call_user_func($this->callback, $this);
  42.     }
  43.     /**
  44.      * Render the row.
  45.      *
  46.      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
  47.      */
  48.     public function render()
  49.     {
  50.         return view('admin::show.row', ['fields' => $this->fields]);
  51.     }
  52.     /**
  53.      * @return Collection|\Dcat\Admin\Show\Field[]
  54.      */
  55.     public function fields()
  56.     {
  57.         return $this->fields;
  58.     }
  59.     /**
  60.      * Set width for a incomming field.
  61.      *
  62.      * @param int $width
  63.      *
  64.      * @return $this
  65.      */
  66.     public function width($width = 12)
  67.     {
  68.         $this->defaultFieldWidth = $width;
  69.         return $this;
  70.     }
  71.     /**
  72.      * Add field.
  73.      *
  74.      * @param string $name
  75.      * @param string $label
  76.      *
  77.      * @return \Dcat\Admin\Show\Field
  78.      */
  79.     public function field($name, $label = '')
  80.     {
  81.         $field = $this->show->field($name, $label);
  82.         $this->pushField($field);
  83.         return $field;
  84.     }
  85.     /**
  86.      * Add field.
  87.      *
  88.      * @param $name
  89.      *
  90.      * @return \Dcat\Admin\Show\Field|Collection
  91.      */
  92.     public function __get($name)
  93.     {
  94.         $field = $this->show->field($name);
  95.         $this->pushField($field);
  96.         return $field;
  97.     }
  98.     /**
  99.      * @param $method
  100.      * @param $arguments
  101.      *
  102.      * @return \Dcat\Admin\Show\Field
  103.      */
  104.     public function __call($method, $arguments)
  105.     {
  106.         $field = $this->show->__call($method, $arguments);
  107.         $this->pushField($field);
  108.         return $field;
  109.     }
  110.     /**
  111.      * @param \Dcat\Admin\Show\Field $field
  112.      *
  113.      * @return void
  114.      */
  115.     protected function pushField($field)
  116.     {
  117.         $this->fields->push([
  118.             'width'   => $this->defaultFieldWidth,
  119.             'element' => $field,
  120.         ]);
  121.     }
  122. }

里面 __ cal l, __get , field 三个方法都是获取当前行的字段信息,并保存到行的属性,在最后渲染详情的时候先循环 rows(这一步在 Dcat\Admin\Show\Panel 的 render 方法), 在通过上面代码中的 render 方法渲染 rows 的每个字段;如下:

html 如下


  
  1. <div class="box-body">
  2.   <div class="form-horizontal mt-1">
  3.       @if($rows->isEmpty())
  4.           @foreach($fields as $field)
  5.               {!! $field->render() !!}
  6.           @endforeach
  7.       @else
  8.           <div>
  9.               @foreach($rows as $row)
  10.                   {!! $row->render() !!}
  11.               @endforeach
  12.           </div>
  13.       @endif
  14.       <div class="clearfix"></div>
  15.   </div>
  16. </div>


使用代码:

控制器创建一个 detail 方法
 


  
  1. protected function detail($id)
  2.   {
  3.       return Show::make($id, new WxyMaterialItem("brands"), function (Show $show) {
  4.           $show->row(function (Show\Row $row) {
  5.               $row->width(6)->name;
  6.               $row->width(6)->simple_code;
  7.           });
  8.           $show->row(function (Show\Row $row) {
  9.               $row->width(4)->specs;
  10.               $row->width(4)->integral_money;
  11.               $row->width(4)->field("aa", "你好");
  12.           });
  13.           $show->row(function (Show\Row $row) {
  14.               $row->width(4)->mdept_id("部门");
  15.               $row->width(4)->status;
  16.               $row->width(4)->field("brands.name", "品牌");
  17.           });
  18.       });
  19.   }

 

文章来源: lansonli.blog.csdn.net,作者:Lansonli,版权归原作者所有,如需转载,请联系作者。

原文链接:lansonli.blog.csdn.net/article/details/107738601

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。