以编程方式呈现 Laravel 7 组件
Render Laravel 7 component programmatically
我有一个 Laravel 7 组件,看起来像这样
class Input extends Component
{
public $name;
public $title;
public $value;
public $type = 'text';
/**
* Create a new component instance.
*
* @return void
*/
public function __construct($name, $title)
{
$this->name = $name;
$this->title = $title;
$this->value = \Form::getValueAttribute($name);
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.fields.input');
}
}
我可以像这样在我的 Blade 组件中渲染字段:
<x-input name="name" :title="__('My field')" />
我需要在代码中创建和呈现字段,我尝试了以下方法:
$field = new Input('name', 'My field');
$field->render();
这returns一个错误:
Undefined variable: title
我可以看到调用了渲染函数,但 public 属性对视图不可用。我将如何渲染具有 public 属性的组件?
手动将变量添加到视图。不然不行
我已报告此问题,但这不是问题:
只需添加要手动查看的属性即可。如果不将属性设为私有,但不应对此产生影响。只是我的实现。
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view(
'components.fields.input',
['name' => $this->name, 'title' => $this->title]
);
}
试试这个,它在 laravel 8 中对我有用,我检查了 data
函数存在于 laravel 7
中
$field = new Input('name', 'My field');
$field->render()->with($field->data());
** 数据函数包括组件的方法、属性和属性。
我用这个,它也适用于匿名组件。把它放在你的帮助文件中。
/**
* Render a blade component.
* @param string $name Component name, exclude component folder (i.e use "card" instead of "components.card")
* @param array $props Component properties
* @param array $attributes Component attributes
* @return \Illuminate\Contracts\View\View
*/
function viewComponent($name, $props = [], $attributes = []) {
$className = collect(explode('.', $name))->map(function($part) {
return \Str::studly($part);
})->join('\');
$className = "App\View\Components\{$className}";
if(class_exists($className)) {
$reflection = (new \ReflectionClass($className))->getConstructor();
$parameters = [];
foreach ($reflection->getParameters() as $param) {
$parameters[] = $props[$param->name] ?? $param->getDefaultValue();
}
$component = new $className(...$parameters);
$component->withAttributes($attributes);
return $component->render()->with($component->data());
}
$props['attributes'] = new \Illuminate\View\ComponentAttributeBag($attributes);
return view("components.$name", $props);
}
用法
viewComponent('input', [
'name' => 'name',
'title' => 'My Field',
]);
// if you want custom attribute
viewComponent('input', [
'name' => 'name',
'title' => 'My Field',
], [
'autocomplete' => 'off',
'data-custom' => 'custom attribute',
]);
last release (v.8.80) of Laravel should help you achieve what you're trying to do with the pull #40425
Blade::render('<x-input name="name" :title="$title" />', ['title' => __('My field')]);
我有一个 Laravel 7 组件,看起来像这样
class Input extends Component
{
public $name;
public $title;
public $value;
public $type = 'text';
/**
* Create a new component instance.
*
* @return void
*/
public function __construct($name, $title)
{
$this->name = $name;
$this->title = $title;
$this->value = \Form::getValueAttribute($name);
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view('components.fields.input');
}
}
我可以像这样在我的 Blade 组件中渲染字段:
<x-input name="name" :title="__('My field')" />
我需要在代码中创建和呈现字段,我尝试了以下方法:
$field = new Input('name', 'My field');
$field->render();
这returns一个错误:
Undefined variable: title
我可以看到调用了渲染函数,但 public 属性对视图不可用。我将如何渲染具有 public 属性的组件?
手动将变量添加到视图。不然不行
我已报告此问题,但这不是问题:
只需添加要手动查看的属性即可。如果不将属性设为私有,但不应对此产生影响。只是我的实现。
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\View\View|string
*/
public function render()
{
return view(
'components.fields.input',
['name' => $this->name, 'title' => $this->title]
);
}
试试这个,它在 laravel 8 中对我有用,我检查了 data
函数存在于 laravel 7
$field = new Input('name', 'My field');
$field->render()->with($field->data());
** 数据函数包括组件的方法、属性和属性。
我用这个,它也适用于匿名组件。把它放在你的帮助文件中。
/**
* Render a blade component.
* @param string $name Component name, exclude component folder (i.e use "card" instead of "components.card")
* @param array $props Component properties
* @param array $attributes Component attributes
* @return \Illuminate\Contracts\View\View
*/
function viewComponent($name, $props = [], $attributes = []) {
$className = collect(explode('.', $name))->map(function($part) {
return \Str::studly($part);
})->join('\');
$className = "App\View\Components\{$className}";
if(class_exists($className)) {
$reflection = (new \ReflectionClass($className))->getConstructor();
$parameters = [];
foreach ($reflection->getParameters() as $param) {
$parameters[] = $props[$param->name] ?? $param->getDefaultValue();
}
$component = new $className(...$parameters);
$component->withAttributes($attributes);
return $component->render()->with($component->data());
}
$props['attributes'] = new \Illuminate\View\ComponentAttributeBag($attributes);
return view("components.$name", $props);
}
用法
viewComponent('input', [
'name' => 'name',
'title' => 'My Field',
]);
// if you want custom attribute
viewComponent('input', [
'name' => 'name',
'title' => 'My Field',
], [
'autocomplete' => 'off',
'data-custom' => 'custom attribute',
]);
last release (v.8.80) of Laravel should help you achieve what you're trying to do with the pull #40425
Blade::render('<x-input name="name" :title="$title" />', ['title' => __('My field')]);