【问题标题】:Failing validation doesn't stop code execution in livewire component验证失败不会停止 livewire 组件中的代码执行
【发布时间】:2021-04-17 19:55:44
【问题描述】:

我正在尝试显示模型列表。使用文本过滤器没有问题,但在尝试添加年份过滤器时,问题开始出现。

如果从fromto 输入发回一个非数字值,我希望验证能够捕获它并将一些错误闪现到会话中,但我仍然收到SQL 错误,因为fromto 不是数字(例如:invalid input syntax for integer: "2020a" (SQL: select * f rom "my_models" where "year" between 2020a and 2021)

Livewire 组件代码

class ModelList extends Component
{
    use WithPagination;
    
    public $from;
    public $to;
    public $search;

    protected $models;

    protected $rules = [
        'from'   => ['required', 'integer', 'between:1970,2021'],
        'to'     => ['required', 'integer', 'between:1970,2021'],
        'search' => ['nullable', 'string'],
    ];

    public function mount()
    {
        $this->from   = (int) date('Y') - 10;
        $this->to     = (int) date('Y');
        $this->search = null;

        $this->doQuery();
    }

    public function updating($name, $value)
    {
        $this->validate();
        $this->doQuery();
        $this->resetPage();
    }

    public function render()
    {
        return view('livewire.list', ['models' => $this->models]);
    }

    protected function doQuery()
    {
        $this->models = MyModel::query()
            ->whereBetween('year', [$this->from, $this->to])
            ->search($this->search)
            ->orderByDesc('year')
            ->paginate(10);
    }
}

查看

<div>
    <div id="filters" class="flex flex-col text-gray-800">
        <div>
            <input type="number" wire:model.lazy="from" min="1970" max="{{ date('Y') }}">
            @error('from')
                <span class="text-red-800">{{ $message }}</span>
            @enderror
        </div>
        <div>
            <input type="number" wire:model.lazy="to" min="1970" max="{{ date('Y') }}">
            @error('to')
                <span class="text-red-800">{{ $message }}</span>
            @enderror
        </div>
        <div>
            <input type="text" wire:model.lazy="search">
            @error('search')
                <span class="text-red-800">{{ $message }}</span>
            @enderror
        </div>
    </div>
    <div id="list">
        @foreach ($models as $model)
            {{ $model->id }}<br>
        @endforeach
    </div>
    <div id="pagination">
        {{ $models->links() }}
    </div>
</div>

我尝试过不同的方法,例如

  • 只是在render() 方法内进行查询,内联doQuery() 方法。
  • 只是在updating() 方法中进行查询。
  • 只是在mount() 方法中进行查询。
  • updating()mount()render() 方法中执行查询。
  • render() 内部调用$this-&gt;validate()

但上述方法似乎都不适用于错误的输入。有时$models 未设置,我在调用links() 方法时收到错误消息。如果这没有发生,那么我会收到一个 SQL 错误,因为错误的输入直接通过了验证。

我知道我可以使用选择输入或添加一些 javascript 来防止非数字值,但这并不能解决无法信任 Livewire 来验证我的输入的根本问题。 (而且只需要打开控制台并写几行代码就可以完全使这种脆弱的验证无效。)

【问题讨论】:

    标签: php laravel laravel-livewire


    【解决方案1】:

    如果您真的想验证您的输入,您必须将您的输入字段包装到一个表单标签中。喜欢:

    <form>
        <div id="filters" class="flex flex-col text-gray-800">
            <div>
                <input type="number" wire:model.lazy="from" min="1970" max="{{ date('Y') }}">
                @error('from')
                    <span class="text-red-800">{{ $message }}</span>
                @enderror
            </div>
            <div>
                <input type="number" wire:model.lazy="to" min="1970" max="{{ date('Y') }}">
                @error('to')
                    <span class="text-red-800">{{ $message }}</span>
                @enderror
            </div>
            <div>
                <input type="text" wire:model.lazy="search">
                @error('search')
                    <span class="text-red-800">{{ $message }}</span>
                @enderror
            </div>
        </div>
    </form>
    

    【讨论】:

      猜你喜欢
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-06
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多