我有一个 Blazor Web App 应用程序。它有一个 Telerik 向导。第一步,我渲染一个 Stripe Address Web 元素。这是我的
App.razor
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="WizardDemo.styles.css" />
<link rel="stylesheet" href="https://blazor.cdn.telerik.com/blazor/5.1.1/kendo-theme-bootstrap/all.css" />
<HeadOutlet />
<script src="https://blazor.cdn.telerik.com/blazor/5.1.1/telerik-blazor.min.js" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/7.0.2/signalr.min.js"></script>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
它具有 Telerik Blazor 和 Stripe Web Elements 的
<link/>
和 <script/>
标签。这是 Home.razor
(结账)页面:
@page "/"
@inject IJSRuntime JS
@rendermode InteractiveServer
@using Telerik.Blazor
@using Telerik.Blazor.Components
<PageTitle>Checkout</PageTitle>
<h3>Checkout</h3>
<div style="width: 600px; margin: 0 auto;">
<TelerikWizard StepperPosition="@Position">
<WizardSteps>
<WizardStep Label="Address" Disabled="StepsDisable[0]">
<Content>
<form id="address-form">
<h3>Address</h3>
<div id="address-element">
<!-- Elements will create form elements here -->
</div>
</form>
</Content>
</WizardStep>
<WizardStep Label="Payment" Disabled="StepsDisable[1]">
<Content>
<h1>Payment Entry</h1>
</Content>
</WizardStep>
<WizardStep Label="Review" Disabled="StepsDisable[2]">
<Content>
<h1>Confirmation</h1>
</Content>
</WizardStep>
</WizardSteps>
<WizardSettings>
<WizardStepperSettings Linear="true" StepType="StepperStepType.Steps" />
</WizardSettings>
</TelerikWizard>
</div>
@code {
IJSObjectReference? module;
public WizardStepperPosition Position { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
module = await JS.InvokeAsync<IJSObjectReference>("import", "./Components/Pages/Home.razor.js");
await module.InvokeVoidAsync("initializeAddress");
}
}
public Dictionary<int, bool> StepsDisable { get; set; } = new Dictionary<int, bool>
{
{0, false},
{1, false},
{2, false},
};
public List<Step> Steps { get; set; } = new List<Step>
{
new Step { Index = 0, Text="Step 1" },
new Step { Index = 1, Text="Step 2" },
new Step { Index = 2, Text="Step 3" }
};
public class Step
{
public int Index { get; set; }
public string? Text { get; set; }
}
}
这是一个带有
TelerikWizard
的服务器页面。请注意,我的第一个 Step
有一个 form
和 address-form
id
。在 OnAfterRender
中,它导入 Home.razor.js
组件,然后调用 initialzeAddress
函数,如下所示:
let elements = {};
export const initializeAddress = () => {
// Set your publishable key: remember to change this to your live publishable key in production
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = Stripe('<my-public-test-key>');
const options = {
// Fully customizable with appearance API.
appearance: { /* ... */ }
};
// Only need to create this if no elements group exist yet.
// Create a new Elements instance if needed, passing the
// optional appearance object.
elements = stripe.elements(/*options*/);
// Create and mount the Address Element in shipping mode
const addressElement = elements.create("address", {
mode: "billing",
});
addressElement.mount("#address-element");
}
export const handleNextStep = async () => {
const addressElement = elements.getElement('address');
return await addressElement.getValue();
};
首次打开页面时,这会成功加载 Stripe Address Web 元素。我可以填写表格并且它可以正常工作。
当我单击
Next
按钮,然后单击 Previous
按钮时,就会出现问题,使我返回到地址步骤。我希望看到地址。但是,我什么也没看到 - 地址表单根本不呈现。
当我单击“上一步”按钮返回到该步骤时,如何获取要渲染的地址?
当您返回时,
<WizardStep Label="Address" Disabled="StepsDisable[0]">
部分将由 Blazor 重新渲染(内部包含初始表单)。
但是页面的其余部分将不会再次进行(第一次)渲染。
await module.InvokeVoidAsync("initializeAddress");
行不再执行。
如果 TelerikWizard 有一些 StepChanged 事件,那么这将是再次初始化的地方。
否则,将地址表单包装在 Blazor 组件中并在其中使用 OnAfterRender 代码。