Laravel基于类的组件类被忽略。

huangapple go评论69阅读模式
英文:

Laravel class based components class being ignored

问题

我在app/view/components/modules/Exchange/common文件夹中创建了Laravel组件,然后在代码中像这样使用该组件:

<x-modules.Exchange.common.text-input placeholder="{{ __('Email') }}"
                                label="{{ __('Email') }}" icon="ni ni-envelope" id="email_input"
                                name="account_email" />

问题是,组件类的构造函数和默认值完全被忽略了,Laravel直接渲染与该组件关联的blade.php文件。当然,没有将默认值传递给blade,这就是我收到此错误的原因:

错误!http状态:500
未定义变量$type(视图:/var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php)(视图:/var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php)

在我的开发环境(Windows)中,它没有任何错误,并且类构造函数被调用,然而,当我部署到ECS Linux时,我遇到了这个错误。这个错误发生在我的所有组件中。

我尝试了composer dum-autoload,php artisan view:clear,php artisan cache:clear,php artisan config:clear,并尝试注册组件。

有人可以帮助解决这个问题吗?
我正在Linux上使用:

Laravel 9.41.0
PHP 8.1.2

提前感谢。

编辑:我的所有类都符合PSR-4
编辑:
TextInput类

<?php

namespace App\View\Components\modules\Exchange\common;

use Illuminate\View\Component;

class TextInput extends Component
{
    public $icon = null;

    public $name = '';

    public $placeholder = '';

    public $label = '';

    public $id = null;

    public $type = 'text';

    public $tab_index = 0;

    public $value = null;

    public $on_change = null;

    public $on_key_down = null;

    public $is_read_only;

    public $class;

    public function __construct(
        $label = '',
        $name = '',
        $icon = null,
        $placeholder = '',
        $id = null,
        $type = 'text',
        $tabIndex = 0,
        $value = null,
        $onChange = null,
        $isReadOnly = false,
        $onKeyDown = null,
        $class = '',
    ) {
        $this->icon = $icon;
        $this->name = $name;
        $this->label = $label;
        $this->placeholder = $placeholder;
        $this->id = $id;
        $this->type = $type;
        $this->tab_index = $tabIndex;
        $this->value = $value;
        $this->on_change = $onChange;
        $this->on_key_down = $onKeyDown;
        $this->is_read_only = $isReadOnly;
        $this->class = $class;
    }

    /**
     * 获取表示组件的视图/内容。
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
        return view('components.modules.Exchange.common.text-input');
    }
}

test-input.blade.php

<div class="form-group w-100" tabindex="">
    @if (isset($label))
        <label class="form-label" for="{{ $id }}">{{ __($label) }}</label>
    @endif
    <div class="input-group">
        @if ($icon)
            <div class="input-group-prepend">
                <span class="input-group-text"><i class="{{ $icon }}"></i></span>
            </div>
        @endif
        @if ($type != 'text_area')
            <input {{ $is_read_only ? 'readonly' : '' }} @if ($type == 'number') step="0.01" @endif
                type="{{ $type }}" name="{{ $name }}"
                @if ($id) id="{{ $id }}" @endif
                @if ($type != 'checkbox') class="form-control {{ $class }}" @endif
                placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
                onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}">
        @else
            <textarea {{ $is_read_only ? 'readonly' : '' }} rows="3" name="{{ $name }}"
                @if ($id) id="{{ $id }}" @endif class="form-control {{ $class }}"
                placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
                onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}"></textarea>
        @endif
    </div>
</div>

<details>
<summary>英文:</summary>
I have laravel component created in nested folders in app/view/components/modules/Exchange/common
and i use this component like this in the code:

<x-modules.Exchange.common.text-input placeholder="{{ __('Email') }}"
label="{{ __('Email') }}" icon="ni ni-envelope" id="email_input"
name="account_email" />


the problem is that component class that has constructor and default values are being ignored completely
and Laravel renders the blade.php associated with that component directly.
And of course no default values are being passed to blade, that&#39;s why I get this error:

Error ! with http_status: 500
Undefined variable $type (View: /var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php) (View: /var/www/html/laravel/resources/views/components/modules/Exchange/common/text-input.blade.php)


In my development environment (Window) it works without any errors and the class constructor is invoked, however, when I deployed to ECS Linux I got that error.
that error occurs in all of my components.
I tried **composer dum-autoload**, **php artisan view:clear**, **php artisan cache:clear**, **php artisan config:clear** and I tried to register the component.
Can anyone help with this issue please?
I&#39;m using on Linux

Laravel 9.41.0
PHP 8.1.2


Thanks in advance.
Edit: All of my classes comply for PSR-4
Edit:
TextInput class

<?php

namespace App\View\Components\modules\Exchange\common;

use Illuminate\View\Component;

class TextInput extends Component
{
public $icon = null;

public $name = &#39;&#39;;
public $placeholder = &#39;&#39;;
public $label = &#39;&#39;;
public $id = null;
public $type = &#39;text&#39;;
public $tab_index = 0;
public $value = null;
public $on_change = null;
public $on_key_down = null;
public $is_read_only;
public $class;
public function __construct(
$label = &#39;&#39;,
$name = &#39;&#39;,
$icon = null,
$placeholder = &#39;&#39;,
$id = null,
$type = &#39;text&#39;,
$tabIndex = 0,
$value = null,
$onChange = null,
$isReadOnly = false,
$onKeyDown = null,
$class = &#39;&#39;,
) {
$this-&gt;icon = $icon;
$this-&gt;name = $name;
$this-&gt;label = $label;
$this-&gt;placeholder = $placeholder;
$this-&gt;id = $id;
$this-&gt;type = $type;
$this-&gt;tab_index = $tabIndex;
$this-&gt;value = $value;
$this-&gt;on_change = $onChange;
$this-&gt;on_key_down = $onKeyDown;
$this-&gt;is_read_only = $isReadOnly;
$this-&gt;class = $class;
}
/**
* Get the view / contents that represent the component.
*
* @return \Illuminate\Contracts\View\View|\Closure|string
*/
public function render()
{
return view(&#39;components.modules.Exchange.common.text-input&#39;);
}

}


test-input.blade.php

<div class="form-group w-100" tabindex="">
@if (isset($label))
<label class="form-label" for="{{ $id }}">{{ __($label) }}</label>
@endif
<div class="input-group">
@if ($icon)
<div class="input-group-prepend">
<span class="input-group-text"><i class="{{ $icon }}"></i></span>
</div>
@endif
@if ($type != 'text_area')
<input {{ $is_read_only ? 'readonly' : '' }} @if ($type == 'number') step="0.01" @endif
type="{{ $type }}" name="{{ $name }}"
@if ($id) id="{{ $id }}" @endif
@if ($type != 'checkbox') class="form-control {{ $class }}" @endif
placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}">
@else
<textarea {{ $is_read_only ? 'readonly' : '' }} rows="3" name="{{ $name }}"
@if ($id) id="{{ $id }}" @endif class="form-control {{ $class }}"
placeholder="{{ __($placeholder) }}" tabindex="{{ $tab_index }}" value="{{ $value }}"
onchange="{{ $on_change }}" onkeydown="{{ $on_key_down }}"></textarea>
@endif

&lt;/div&gt;

</div>


</details>
# 答案1
**得分**: 1
经过大量的搜索和实验,我找到了解决方案。
我之前的代码是这样的:
```html
&lt;x-modules.Exchange.common.text-input placeholder=&quot;{{ __(&#39;Email&#39;) }}&quot;
label=&quot;{{ __(&#39;Email&#39;) }}&quot; icon=&quot;ni ni-envelope&quot; id=&quot;email_input&quot;
name=&quot;account_email&quot; /&gt;

是吗?

我需要将组件路径中的每个单词都大写,就像这样 x-Modules.Exchange.Common,然后大写这条路径中的文件夹名称,它就立刻生效了。

所以我假设 Laravel 大写类基础组件的路径,然后操作系统开始发挥作用,如果它是大小写不敏感的,它会找到组件类,如果不是(在 Linux 的情况下),您必须大写文件夹名称以让操作系统找到它。

英文:

After searching and experementing a lot I found the solution solution.

I was doing

&lt;x-modules.Exchange.common.text-input placeholder=&quot;{{ __(&#39;Email&#39;) }}&quot;
label=&quot;{{ __(&#39;Email&#39;) }}&quot; icon=&quot;ni ni-envelope&quot; id=&quot;email_input&quot;
name=&quot;account_email&quot; /&gt;

right?

i need to capitalize every word in the component path like this x-Modules.Exchange.Common

and then capitalize folders names along this path and it worked right away.

So I'm assuming that Laravel capitalize class based components paths and try to find them then the OS comes into play, if it's case-insensetive it will find the component class and it's not (in case of linux) you have to capitalize your folders names to let the OS find it.

答案2

得分: 0

感谢提供额外的代码片段。以下是我的更新回复。

在 Laravel 的 Blade 模板中,当使用组件时,需要在包含组件时显式传递组件的属性。组件类本身内设置的默认值不会在没有显式传递相应属性的情况下自动使用。

构造函数负责根据组件包含过程中传递的值来初始化属性。因此,如果不传递任何参数给构造函数,它将不会使用类内部设置的默认值。

您可以像这样设置默认值:

class TextInputComponent extends Component
{
    public $type;

    public function __construct($type = null)
    {
        $this->type = $type ?: 'text';
    }

    public function render()
    {
        return view('components.modules.Exchange.common.text-input');
    }
}

这一行 $this->type = $type ?: 'text'; 使用了空合并运算符(?:)。它会将 $type 的值分配给 $type 属性,如果 $type 不为 null,否则,它将 $type 属性赋值为默认值 'text'

这意味着如果您在 Blade 模板中包含 TextInput 组件时没有显式传递 $type 属性,将自动使用默认值 'text'

您可以尝试使用相同的方法设置其他不需要显式传递值的变量。

英文:

Thanks for providing additional code snippets. Here is my updated response.

In Laravel's Blade templates, when using components, the component's properties need to be passed explicitly when including the component. The default values set within the component class itself will not be automatically used if the corresponding property is not explicitly passed.

The constructor is responsible for initializing the properties based on the values passed during component inclusion. So if you don't pass any arguments to the constructor, it won't use the default value you set within the class.

You try setting your default values like this:

class TextInputComponent extends Component
{
public $type;
public function __construct($type = null)
{
$this-&gt;type = $type ?: &#39;text&#39;;
}
public function render()
{
return view(&#39;components.modules.Exchange.common.text-input&#39;);
}
}

The line $this-&gt;type = $type ?: &#39;text&#39;; utilizes the null coalescing operator (?:). It assigns the value of $type to the $type property if it is not null. However, if $type is null, it assigns the default value of &#39;text&#39; to the $type property.

This means that if you do not explicitly pass the $type attribute when including the TextInput component in your Blade template, the default value of &#39;text&#39; will be used automatically.

You may try this with the rest of your variables that you don't want to explicitly pass a value.

huangapple
  • 本文由 发表于 2023年6月18日 17:44:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76499902.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定