【问题标题】:Livewire loading state from javascript (async)来自 javascript (async) 的 Livewire 加载状态
【发布时间】:2021-11-25 04:42:24
【问题描述】:

我有一个向 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)
    }

});

如果上面的async方法响应成功,会触发Livewire组件下面的方法:

public function addPaymentMethod($paymentMethod)
{
   //Create the payment method in Stripe...
   auth()->user()->addPaymentMethod($paymentMethod);

   //Other validation etc...

}

所有这些的输出都在下面的 gif 中捕获。正如您在此处看到的,用户输入信用卡详细信息并单击“添加支付卡”并被重定向到另一个页面。

问题是,加载状态会开始一段时间,但在实际请求/重定向完成之前就消失了。

在对 Stripe 的实际请求完成之前,如何显示加载微调器?

【问题讨论】:

  • 我认为你需要使用队列
  • @Mauro 为此我不能使用队列,因为我还需要在 Stripe 中处理 SCA。

标签: laravel laravel-livewire alpine.js


【解决方案1】:

这取决于addPaymentMethod 中还发生了什么,以及为什么您的加载状态会提前隐藏。为了让您更好地控制该时间,我可能会将您的加载状态的显示/隐藏推迟到 javascript 层。以下是几种处理方法:

1。使用承诺

Livewire 的一个很好的特性是,当您的组件方法通过 javascript 调用时,它们会在完成后返回一个 Promise。因此,如果您需要隐藏加载状态,您可以在此处执行此操作:

// The card has been verified successfully...
@this.addPaymentMethod(setupIntent.payment_method)
    .then(result => {
        // Hide loading state
    })

2。发出事件

另一种方法是使用emit an event from the 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-05
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多