我有一个问题,闪存消息不显示时使用Laravel Livewire。
如果我只使用wire:model,然后单击save按钮,一切正常,并显示成功消息。但是如果我使用wire:model。延迟flash消息只在页面刷新后工作一次,因此,例如,页面加载时,我更改了一个表单字段,然后单击SaveEverything。但是,假设我忘记更改字段,现在单击save,只有在重新加载页面时,才会显示flash消息。
这个人似乎有同样的问题,但没有提供解决方案。同样的问题?
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
class ProfileSettings extends Component
{
public $display_name;
public $bio;
public $location;
public $website_url;
public $subscription;
public $hide_status;
public $hide_profile;
public function UpdateProfile()
{
$validatedData = $this->validate(
[
'display_name' => ['required', 'string', 'min:3', 'max:40', 'regex:/^[a-zA-Z0-9.\s]+$/'],
'bio' => ['nullable', 'string', 'max:1000'],
'location' => ['nullable', 'string', 'max:100'],
'website_url' => ['nullable', 'max:100', 'url'],
'subscription' => ['nullable', 'numeric', 'min:4.99', 'max:29.99'],
'hide_status' => 'boolean',
'hide_profile' => 'boolean',
]
);
// Store subscription price in cents.
if($validatedData['subscription'])
$validatedData['subscription'] = $this->subscription * 100;
else
$validatedData['subscription'] = NULL;
User::where('id', auth::user()->id)->update($validatedData);
session()->flash('message', 'Profile settings successfully updated!');
}
// Populate the form fields with stored data.
public function mount() {
$this->display_name = Auth::user()->display_name;
$this->bio = Auth::user()->bio;
$this->location = Auth::user()->location;
$this->website_url = Auth::user()->website_url;
// If a subscription price is set, convert from cents to dollars
// with two decimal places for displaying.
if (Auth::user()->subscription)
{
$dollars = Auth::user()->subscription / 100;
$this->subscription = number_format($dollars, 2, '.', ',');
}
$this->hide_status = Auth::user()->hide_status;
$this->hide_profile = Auth::user()->hide_profile;
}
public function render()
{
return view('livewire.profile-settings');
}
}
<div>
<h3 class="text-xl mb-2">Profile</h3>
<p>Here you can edit your profile information, privacy and subscription details.</p>
</div>
<div class="bg-white rounded-md lg:shadow-md shadow col-span-2">
<form wire:submit.prevent="UpdateProfile">
<div class="grid grid-cols-1 gap-3 lg:p-6 p-4">
<div>
<label for="display_name">Display Name</label>
<input id="display_name" type="text" class="shadow-none with-border focus:ring-0" wire:model.defer="display_name">
@error('display_name')<x-validation-errors :message="$message"/>@enderror
</div>
<div>
<label for="bio">Bio</label>
<textarea id="bio" rows="3" class="shadow-none bg-gray-100 with-border focus:ring-0" wire:model.defer="bio"></textarea>
@error('bio')<x-validation-errors :message="$message"/>@enderror
</div>
<div>
<label for="location">Location</label>
<input id="location" type="text" class="shadow-none with-border focus:ring-0" wire:model.defer="location">
@error('location')<x-validation-errors :message="$message"/>@enderror
</div>
<div>
<label for="website_url">Website URL</label>
<input id="website_url" type="text" class="shadow-none with-border focus:ring-0" wire:model.defer="website_url">
@error('website_url')<x-validation-errors :message="$message"/>@enderror
</div>
<div>
<label for="subscription">Subscription Price - minimum $4.99 USD per month or leave blank for free.</label>
<div class="flex items-center">
<div class="-mr-1 bg-gray-100 border px-3 py-3 rounded-l-md">$</div>
<input id="subscription" type="text" class="shadow-none with-border focus:ring-0" wire:model.defer="subscription">
</div>
@error('subscription')<x-validation-errors :message="$message"/>@enderror
</div>
<div class="mt-5 space-y-5 ">
<div class="flex justify-between items-center">
<div>
<h4>Activity Status</h4>
<div>Enable to hide your last seen status on your profile.</div>
</div>
<div class="switches-list -mt-8 is-large">
<div class="switch-container">
<input type="hidden" value="0" wire:mode.defer="hide_status">
<label class="switch"><input type="checkbox" value="1" wire:model.defer="hide_status"><span class="switch-button"></span></label>
</div>
</div>
</div>
<hr>
<div class="flex justify-between items-center">
<div>
<h4>Hide Profile</h4>
<div>Enable to hide your profile from search results.</div>
</div>
<div class="switches-list -mt-8 is-large">
<div class="switch-container">
<input type="hidden" value="0"wire:mode.defer="hide_profile" >
<label class="switch"><input type="checkbox" value="1" wire:model.defer="hide_profile"><span class="switch-button"></span></label>
</div>
</div>
</div>
</div>
<div>
<x-auth-session-status class="mb-4" :status="session('message')"/>
</div>
<div class="flex items-center justify-center">
<x-button>
<span wire:loading.delay wire:target="UpdateProfile"><x-loading /></span>
<span wire:loading.remove wire:target="UpdateProfile">{{ __('Save') }}</span>
</x-button>
</div>
</div>
</form>
</div>
</div>
@if ($status)
<div x-data="{ show: true }" x-show="show"
class="flex justify-between items-center bg-green-200 relative py-3 px-3 rounded-lg">
<div>
<div class="ml-2 text-sm text-green-600">
{{ $status }}
</div>
</div>
<div>
<button type="button" @click="show = false" class=" text-green-700">
<span class="text-2xl">×</span>
</button>
</div>
</div>
@endif
我认为这与Livewire
关系不大,而与Alpine
和它的生命周期关系更大。它第一次工作的原因是因为Alpin
组件不在DOM
中,所以当闪存消息被添加到DOM
时,它是用x-data="{show: true初始化的}
以便显示组件。当您单击关闭
按钮将show
的值更改为false
,然后更新某些内容并按保存
,该组件已经在DOM
中,因此不会再次初始化意味着show
的值没有设置为true
。
在Jetstream的Livewaire堆栈中,有使用带有Livewire
和Alpin
的Flash消息的示例。它使用事件而不是会话()。
public function save()
{
// ...
$this->emit('saved');
}
<div x-data="{ shown: false, timeout: null }"
x-init="@this.on('saved', () => { clearTimeout(timeout); shown = true; timeout = setTimeout(() => { shown = false }, 2000); })"
x-show.transition.opacity.out.duration.1500ms="shown"
style="display: none;">
{{ __('Updated.') }}
</div>
这将初始化Alpine
组件,并为saved
事件附加一个侦听器,以便它在听到saved
事件时触发一个函数执行,该函数显示消息,然后清除。
如果您想允许用户手动清除消息,您可以删除setTimeout
内容并将其设置为show=true
。