laravel-admin 之 form
__call 魔术方法使用
这个方法用来监视一个对象中的其它方法。如果你试着调用一个对象中不存在的方法,__call 方法将会被自动调用。
会省略部分代码,只挑取要讲解的内容
Layout
- 布局设置
/**
* Add a new column in layout.
*
* @param int $width
* @param \Closure $closure
*/
public function column($width, \Closure $closure)
{
if ($this->columns->isEmpty()) {
$column = $this->current;
$column->setWidth($width);
} else {
$column = new Column($width);
$this->current = $column;
}
$this->columns->push($column);
$closure($this->parent);
}
$content->row(function(Row $row) {
$row->column(4, 'foo');
$row->column(4, 'bar');
$row->column(4, 'baz');
});
----------------------------------
|foo |bar |baz |
| | | |
| | | |
| | | |
| | | |
| | | |
----------------------------------
Column
- row 获取内容
- build 渲染输出
/**
* Add a row for column.
*
* @param $content
*
* @return Column
*/
public function row($content)
{
if (!$content instanceof \Closure) {
$row = new Row($content);
} else {
$row = new Row();
call_user_func($content, $row);
}
ob_start();
$row->build();
$contents = ob_get_contents();
ob_end_clean();
return $this->append($contents);
}
/**
* Build column html.
*/
public function build()
{
$this->startColumn();
foreach ($this->contents as $content) {
if ($content instanceof Renderable || $content instanceof Grid) {
echo $content->render();
} else {
echo (string) $content;
}
}
$this->endColumn();
}
- 例子
ArticleController
protected function form()
{
$form = new Form(new Article());
$form->image('image', __('Image'));
return $form;
}
Form
- 字段调用实现
- row 链式调用
class Form implements Renderable
{
use HasFields;
public function __call($method, $arguments)
{
if ($className = static::findFieldClass($method)) { // 查找字段是否有对应的类
$column = Arr::get($arguments, 0, ''); //[0];
$element = new $className($column, array_slice($arguments, 1)); // 实例化
$this->pushField($element);
return $element;
}
}
/**
* Add a row in form.
*
* @param Closure $callback
*
* @return $this
*/
public function row(Closure $callback): self
{
$this->rows[] = new Row($callback, $this);
return $this;
}
}
HasFields
- 定义字段和类对应
/**
* 这里的注释IDE 会识别提示
*
* @method Field\Image image($column, $label = '')
*/
trait HasFields
{
/**
* Available fields.
*
* @var array
*/
public static $availableFields = [
'image' => Field\Image::class,
];
}
Image
- 前面设置的各种参数在这里渲染
public function render()
{
return Admin::component($this->getView(), $this->variables());
}
HasAssets
- 渲染的具体实现
- 渲染结果
- 分析html
- 对 html dom 树分析插入需要的代码
- 返回渲染后的字符串
trait HasAssets
{
/**
* @param $component
*/
public static function component($component, $data = [])
{
$string = view($component, $data)->render();
$dom = new \DOMDocument();
libxml_use_internal_errors(true);
$dom->loadHTML('<?xml encoding="utf-8" ?>'.$string);
libxml_use_internal_errors(false);
}
}
helpers
助手函数
- view 获取实例,解析内容
- render 获取内容
if (! function_exists('view')) {
/**
* Get the evaluated view contents for the given view.
*
* @param string|null $view
* @param \Illuminate\Contracts\Support\Arrayable|array $data
* @param array $mergeData
* @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
*/
function view($view = null, $data = [], $mergeData = [])
{
$factory = app(ViewFactory::class);
if (func_num_args() === 0) {
return $factory;
}
return $factory->make($view, $data, $mergeData);
}
}
form.blade.php
- row 调用渲染
- columns 调用渲染
<div class="box-body">
@if(!$tabObj->isEmpty())
@include('admin::form.tab', compact('tabObj'))
@else
<div class="fields-group">
@if($form->hasRows())
@foreach($form->getRows() as $row)
{!! $row->render() !!}
@endforeach
@else
@foreach($layout->columns() as $column)
<div class="col-md-{{ $column->width() }}">
@foreach($column->fields() as $field)
{!! $field->render() !!}
@endforeach
</div>
@endforeach
@endif
</div>
@endif
</div>
<!-- /.box-body -->
本作品采用《CC 协议》,转载必须注明作者和本文链接