【问题标题】:How in laravel-livewire set flash message with validation erros如何在 laravel-livewire 中设置带有验证错误的 flash 消息
【发布时间】:2021-01-07 04:29:18
【问题描述】:

在登录表单中使用 laravel 7 /livewire 1.3 应用程序时,我在无效表单上收到错误代码:

public function submit()
{
    $loginRules= User::getUserValidationRulesArray();
    $this->validate($loginRules);

并在任何字段附近显示错误消息

我想在登录失败时添加 Flash 消息和阅读 https://laravel.com/docs/7.x/validation

我试着做:

$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);

if ($validator->fails()) {
    session()->flash('danger_message', 'Check your credentials !');
    return redirect()->to('/login');
}

我收到了 Flash 消息,但任何字段的验证错误都丢失了。

如果我尝试做:

$request = request();
$loginRules= User::getUserValidationRulesArray('login');
$validator = Validator::make($request->all(), $loginRules);

if ($validator->fails()) {
    session()->flash('danger_message', 'Check your credentials !');
    return redirect('/login')
        ->withErrors($validator)
        ->withInput();
}

我得到了错误:

Method Livewire\Redirector::withErrors does not exist.

在 routes/web.php 我有:

Route::livewire('/login', 'login')->name('login');

修改: 在组件 app/Http/Livewire/Login.php 中:

<?php

namespace App\Http\Livewire;

use App\User;
use Illuminate\Support\Facades\Validator;
use Livewire\Component;
use Auth;
use DB;
use App\Config;
use Cartalyst\Sentinel\Laravel\Facades\Sentinel;


class Login extends Component
{
    public $form= [
        'email'=>'admin@mail.com',
        'password'=> '111111',
    ];

    private $view_name= 'livewire.auth.login';


    public function submit()
    {

        $request = request();
        $loginRules= User::getUserValidationRulesArray('login');
        $validator = Validator::make($request->all(), $loginRules);

        if ($validator->fails()) {
            session()->flash('danger_message', 'Check your credentials !');
            return;
//            return redirect()->to('/login');
        }



        $user = Sentinel::findByCredentials(['email'    => $this->form['email']]);
        if (empty($user)) {
            session()->flash('danger_message', 'User "' . $this->form['email'] . '" not found !');
            ...

和模板资源/views/livewire/auth/login.blade.php:

<article >

    @include('livewire.common.alert_messages')

       <form class="form-login" wire:submit.prevent="submit">

        <div class="card">
                   @if ($errors->any())
                Check your login credentials
            @endif

                <ul>
                 @foreach ($errors->all() as $error)
                        <li>{{ $error }}</li>
                                          @endforeach
                </ul>

            <div class="card-body card-block">

                <h3 class="card-header">
                    <span class="spinner-border" role="status" wire:loading>
                        <span class="sr-only">Loading...</span>
                    </span>
                    Login
                    </h3>
                <h4 class="card-subtitle">Use your credentials</h4>

                <dl> <!-- email FIELD DEFINITION -->

                    <dt>
                        <label class="col-form-label" for="email">Email:<span class="required"> * </span></label>
                    </dt>
                    <dd>
                            <input
                                wire:model.lazy="form.email"
                                name="email"
                                id="email"
                                class="form-control"
                                placeholder="Your email address"
                                autocomplete=off
                                             >
                          @error('form.email')
                        <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
                    </dd>
                </dl> <!-- <dt> email FIELD DEFINITION -->


                <dl> <!-- password FIELD DEFINITION -->
                    <dt>
                        <label class="col-form-label" for="password">Password:<span class="required"> * </span></label>
                    </dt>
                    <dd>
                         <input type="password"
                               wire:model.lazy="form.password"
                                   id="password"
                                   name="password"
                                   class="form-control"
                                   placeholder="Your password"
                                   autocomplete=off
                                                >
                          @error('form.password')
                        <div class="validation_error">{{ clearValidationError($message,['form.'=>'']) }}</div> @enderror
                    </dd>
                </dl> <!-- <dl> password FIELD DEFINITION -->

            </div> <!-- <div class="card-body card-block"> -->

            <section class="card-footer row_content_right_aligned">
                <button type="reset" class="btn btn-secondary btn-sm m-2">
                    Reset
                </button>
                <button type="submit" class="btn btn-primary btn-sm m-2 ml-4 mr-4 action_link">
                    Submit
                </button>
            </section>


        </div> <!-- <div class="card"> -->

    </form>
</article>

哪种方式有效?

提前致谢!

【问题讨论】:

  • 阅读此laravel-livewire.com/docs/1.x/… 并遵循它与 Laravel 有点不同
  • 不确定我要遵循什么?我必须使用 validateOnly 吗?
  • 过去你的组件代码不在 laravel 代码中

标签: laravel laravel-livewire


【解决方案1】:

Livewire 的美妙之处在于您不一定需要重定向来显示消息,您可以通过在组件上设置属性来显示消息,并有条件地在视图中呈现它们。在这种特殊情况下,已经有现成可用的逻辑,您只需检查验证所暴露的错误对象。

在您看来,您所要做的就是检查@if ($errors-&gt;any()) - 如果这是真的,请显示您的信息。这是 Livewire 实现的 Laravel 功能。当任何验证失败时,都会引发并拦截异常,并且 $errors 变量会暴露在您的视图中。这意味着无论何时您执行$this-&gt;validate(),并且验证失败,您都可以访问$errors 中的错误。

<div>
    @if ($errors->any())
        Check your login credentials
    @endif 

    <form wire:submit.prevent="submit">
        <input type="text" wire:model="email">
        @error('email') <span class="error">{{ $message }}</span> @enderror
        
        <input type="password" wire:model="password">
        @error('password') <span class="error">{{ $message }}</span> @enderror
    
        <button type="submit">Submit</button>
    </form>
</div>

使用$rules 属性声明规则,使用$this-&gt;validate() 验证这些规则,Livewire 将为您完成大部分工作。您不需要返回任何重定向,或使用session()-&gt;flash()。会话状态不会闪烁,因为您没有执行新的页面加载。

class Login extends Component
{
    public $form = [
        'email' => 'admin@mail.com',
        'password' => '111111',
    ];

    protected $rules;

    private $view_name = 'livewire.auth.login';

    public function submit()
    {
        $this->rules = User::getUserValidationRulesArray('login');
        $this->validate();

        // No need to do any more checks, $errors will now be updated in your view as the exception is thrown
        // Proceed with submitting the form

【讨论】:

  • 我在组件中评论了重定向,但是这个流程: if ($errors->any()) 检查您的登录凭据 endif 未呈现。看起来像设置 flash 消息 @error('password') 丢失了。
  • 那么您可能正在做一些其他奇怪的事情,因为简单地检查@if ($errors-&gt;any()) 不会干扰@error 刀片指令。我只是在本地测试了一下,可以同时使用。
  • 我需要用 1 条预定义消息代替阻止 @if ($errors->any()) 来显示 Flash 消息
  • 使用提供的$rules 属性和$this-&gt;validate() 而不是自己编写。请参阅组件示例。
  • 但在这种情况下,流程会自动停止在 $this->validate([ ]);我不能在下一行设置闪光灯。而且我没有看到任何触发事件以在下一行设置闪存。这就是问题所在,为什么要使用 Validator::make(
【解决方案2】:

在 render 方法之前你可以检查 errorBag 是否有项目:


    public function render()
    {
        if(count($this->getErrorBag()->all()) > 0){

             $this->emit('error:example');

        }
        return view('livewire-component-view');
    }

【讨论】:

    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多