来自 javascript 的 Livewire 加载状态(异步)
2021-10-04
3085
我有一个向 Stripe 发送请求的表单,以便我的用户添加付款方式:
<form id="card-form">
<label>Card details</label>
<div id="card-element"></div>
<button wire:target="addPaymentMethod" wire:loading.class="hidden" class="button round" id="card-button">Add payment card</button>
<!-- Loading spinner -->
<svg wire:target="addPaymentMethod" wire:loading class="inline-block animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</form>
(精简的)JavaScript 如下所示:
const stripe = Stripe('stripe-public-key');
const elements = stripe.elements();
const form = document.getElementById('card-form')
const cardButton = document.getElementById('card-button');
const cardElement = elements.create('card');
cardElement.mount('#card-element');
form.addEventListener('submit', async (e) => {
e.preventDefault();
cardButton.disabled = true;
const {
setupIntent,
error
} = await stripe.confirmCardSetup(
clientSecret, {
payment_method: {
card: cardNumber,
billing_details: {
name: 'Oliver'
}
}
}
);
if (error) {
// Display error.message to the user...
cardButton.disabled = false
console.log(error.message)
} else {
// The card has been verified successfully...
@this.addPaymentMethod(setupIntent.payment_method)
}
});
如果上述异步方法中的响应成功,它将触发 Livewire 组件中的以下方法:
public function addPaymentMethod($paymentMethod)
{
//Create the payment method in Stripe...
auth()->user()->addPaymentMethod($paymentMethod);
//Other validation etc...
}
所有这些的输出都捕获在下面的 gif 中。如您在此处所见,用户输入信用卡详细信息并点击“添加支付卡”并重定向到另一个页面。
问题是,加载状态开始了一段时间,但在实际请求/重定向完成之前就消失了。
如何显示加载旋转器,直到对 Stripe 的实际请求完成?
1个回答
这取决于
addPaymentMethod
中还发生了什么,以及为什么您的加载状态会提前隐藏。为了让您更好地控制时间,我可能会将加载状态的显示/隐藏推迟到 javascript 层。这里有几种方法可以解决它:
1. 使用承诺
Livewire 的一个不错的功能是,当通过 javascript 调用组件方法时,它们会在完成后返回一个承诺。因此,如果您需要隐藏加载状态,您可以在此处执行此操作:
// The card has been verified successfully...
@this.addPaymentMethod(setupIntent.payment_method)
.then(result => {
// Hide loading state
})
2.发出事件
另一种方法是
从
addPaymentMethod
发出事件,您可以在组件前端监听该事件。
public function addPaymentMethod($paymentMethod)
{
// Your add payment code runs...
// Emit an event to the frontend (with optional data)
$this->dispatchBrowserEvent('add-payment-method-complete', ['someData' => $value]);
}
您可以使用 AlpineJs 在前端轻松监听此事件。以下是使用 Alpine 管理加载状态的简短表单示例:
<form
// Init AlpineJs with the x-data attribute
x-data="{
isLoading: false
}"
// Listen the forms submit event and change
// our "isLoading" flag to true
x-on:submit="isLoading = true">
// Listen for the event emitted from Livewire to the window
// and reset the isLoading flag to false
<svg x-on:add-payment-method-complete.window="isLoading = false" />
</form>
Steve O
2021-10-11