You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telerik Blazor Wizard点击Previous按钮后无法重新渲染Stripe地址组件

Blazor Web App中Telerik Wizard结合Stripe Address Element的渲染修复方案

问题场景

在Blazor Web App项目中使用Telerik Wizard组件,第一步集成Stripe Address Web Element:

  • 首次加载Wizard的第一步时,地址表单正常渲染且可编辑
  • 点击「Next」进入后续步骤后,再点击「Previous」返回地址步骤,地址表单完全不渲染

解决思路

将Stripe Address Element的渲染逻辑抽离为独立的CheckoutAddress组件,利用Blazor组件的生命周期机制,每次返回地址步骤时都会重新初始化组件,从而触发Stripe Element的重新渲染。

代码实现

1. 独立组件:CheckoutAddress.razor

@inject IJSRuntime JSRuntime
@implements IAsyncDisposable

<div id="address-element"></div>

@code {
    private IJSObjectReference? _stripeModule;
    private IJSObjectReference? _addressElement;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            _stripeModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./StripeCheckout.js");
            _addressElement = await _stripeModule.InvokeAsync<IJSObjectReference>("initializeAddressElement");
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (_addressElement != null)
        {
            await _addressElement.InvokeVoidAsync("destroy");
            await _addressElement.DisposeAsync();
        }

        if (_stripeModule != null)
        {
            await _stripeModule.DisposeAsync();
        }
    }
}

2. Home.razor(Wizard集成)

<TelerikWizard Width="600px" Height="400px">
    <WizardSteps>
        <WizardStep Text="Shipping Address">
            <CheckoutAddress />
        </WizardStep>
        <WizardStep Text="Payment">
            <p>Payment details will go here</p>
        </WizardStep>
        <WizardStep Text="Confirmation">
            <p>Order confirmation will go here</p>
        </WizardStep>
    </WizardSteps>
</TelerikWizard>

3. StripeCheckout.js(JS模块)

import { loadStripe } from '@stripe/stripe-js';

let stripe;
let elements;

export async function initializeAddressElement() {
    stripe = await loadStripe('your-publishable-key');
    elements = stripe.elements();

    const addressElement = elements.create('address', {
        mode: 'shipping',
        fields: {
            addressLine1: 'always',
            addressLine2: 'auto',
            city: 'always',
            state: 'always',
            postalCode: 'always',
            country: 'always'
        }
    });

    addressElement.mount('#address-element');
    return addressElement;
}

4. App.razor(路由配置)

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

原理说明

Telerik Wizard在切换步骤时,非活动步骤的DOM元素会保留状态,但Stripe Element依赖初始化时的DOM挂载操作。抽离为独立组件后,每次返回地址步骤时,组件会重新触发OnAfterRenderAsync生命周期方法,重新初始化并挂载Stripe Address Element,从而解决返回时不渲染的问题。

内容的提问来源于stack exchange,提问作者Joe Mayo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:52:21