我有一个表单,允许用户填写电子剩余的多个字段。它使用浏览器会话存储存储我在 RadzenCard 中拥有的所有字段的数据,然后在摘要页面上的网格视图中从会话存储加载数据(第 2 页)在数据库中更新之前可以查看所有输入的信息。问题是它没有将 sessionData 加载到摘要中的 RadzenGrid 中(第 2 页)
这是第 1 页的代码:
@page "/form"
@using System.Text.Json;
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@inject DialogService DialogService
@inject ContextMenuService ContextMenuService
@inject TooltipService TooltipService
@inject NotificationService NotificationService
@inject NavigationManager NavManager
<PageTitle>Form</PageTitle>
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="h3" style="display: block">Welcome Christopher DeBrodie!</h1>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="form-group">
<RadzenDropDownDataGrid TValue="string" ValueProperty="BuildingName" TextProperty="BuildingName" Data="@buildingLists" Placeholder="School Name" Style="width: 100%" AllowSorting="false" AllowSelectAll="false" AllowFiltering="false" ShowSearch="false" PageSize="60">
<Columns>
<RadzenDropDownDataGridColumn Property="BuildingName" Title="BuildingName" />
</Columns>
</RadzenDropDownDataGrid>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="form-group">
@foreach (var inputData in inputCardData)
{
<div class="col-md-12"> <!-- Add this div to control card width -->
<RadzenCard Variant="Radzen.Variant.Filled">
<div class="form-group">
<RadzenAutoComplete TextProperty="CPSNumber" Data="@surplusItemsNews" @bind-Value="inputData.CPSNumber" Placeholder="CPS Number" Style="width: 100%" />
</div>
<div class="form-group">
<RadzenAutoComplete TextProperty="Description" Data="@surplusItemsNews" @bind-Value="inputData.Description" Placeholder="Item Description" Style="width: 100%" />
</div>
<div class="form-group">
<RadzenDropDownDataGrid TValue="string" ValueProperty="ReasonDescription" TextProperty="ReasonDescription" Data="@reasons" Style="width: 100%" ShowSearch="false" AllowFiltering="false" AllowSorting="false" AllowSelectAll="false" Placeholder="Reason For Surplus" PageSize="10">
<Columns>
<RadzenDropDownDataGridColumn Property="ReasonDescription" Title="ReasonDescription" />
</Columns>
</RadzenDropDownDataGrid>
</div>
</RadzenCard>
</div>
}
</div>
</div>
</div>
</div>
</div>
<RadzenButton Style="width: 100%; min-width: 0px; min-height: 0px; height: 40px; display: block; background-color: #005570" Text="Review" Click="FinalizeList"></RadzenButton>
@code {
[Inject]
protected Surplus.WASPOService WASPOService { get; set; }
protected System.Linq.IQueryable<Surplus.Models.WASPO.SurplusItemsNew> surplusItemsNews;
protected System.Linq.IQueryable<Surplus.Models.WASPO.BuildingList> buildingLists;
protected System.Linq.IQueryable<Surplus.Models.WASPO.Reason> reasons;
// Create a class to hold form data
public class FormData
{
public string CPSNumber { get; set; }
public string Description { get; set; }
public string ReasonDescription { get; set; }
}
// Create a list to store instances of the form data
List<FormData> inputCardData = new List<FormData>(){ new FormData () };
// Function to save inputCardData to session storage
private async Task SaveInputCardDataToSessionStorage()
{
try
{
var json = JsonSerializer.Serialize(inputCardData);
await JSRuntime.InvokeVoidAsync("sessionStorage.setItem", "inputCardData", json);
}
catch (Exception ex)
{
Console.WriteLine($"Error saving to session storage: {ex.Message}");
}
}
// Function to load inputCardData from session storage
private async Task LoadInputCardDataFromSessionStorage()
{
try
{
var json = await JSRuntime.InvokeAsync<string>("sessionStorage.getItem", "inputCardData");
if (!string.IsNullOrEmpty(json))
{
inputCardData = JsonSerializer.Deserialize<List<FormData>>(json);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading from session storage: {ex.Message}");
}
}
protected override async Task OnInitializedAsync()
{
surplusItemsNews = await WASPOService.GetSurplusItemsNews();
buildingLists = await WASPOService.GetBuildingLists();
reasons = await WASPOService.GetReasons();
// Load inputCardData from session storage when the page initializes
await LoadInputCardDataFromSessionStorage();
}
// Event handler for the "Finalize List" button
private async Task FinalizeList()
{
// Save the input card data to session storage
await SaveInputCardDataToSessionStorage();
// Navigate to the summary page
NavManager.NavigateTo("/summary");
}
}
这是第 2 页的代码:
@page "/summary"
@using System.Text.Json;
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@inject DialogService DialogService
@inject ContextMenuService ContextMenuService
@inject TooltipService TooltipService
@inject NotificationService NotificationService
<PageTitle>Summary</PageTitle>
<RadzenGrid Data="@sessionData" TItem="FormData">
<Columns>
<RadzenGridColumn TItem="FormData" Property="CPSNumber" Title="CPS Number" />
<RadzenGridColumn TItem="FormData" Property="Description" Title="Item Description" />
<RadzenGridColumn TItem="FormData" Property="ReasonDescription" Title="Reason For Surplus" />
</Columns>
</RadzenGrid>
@code {
// Define the FormData class if it's not already defined
public class FormData
{
public string CPSNumber { get; set; }
public string Description { get; set; }
public string ReasonDescription { get; set; }
}
// Read the stored session data
private List<FormData> sessionData = new List<FormData>();
protected override async Task OnInitializedAsync()
{
// Load the session data from Session Storage using IJSRuntime
try
{
var storedDataJson = await JSRuntime.InvokeAsync<string>("sessionStorage.getItem", "sessionData");
if (!string.IsNullOrEmpty(storedDataJson))
{
sessionData = JsonSerializer.Deserialize<List<FormData>>(storedDataJson);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading from Session Storage: {ex.Message}");
}
}
}
我对 blazor 的开发还是很陌生,如果这听起来像是一个菜鸟问题,我很抱歉。任何帮助都会很棒!!!
这段代码:
protected override async Task OnInitializedAsync()
{
// Load the session data from Session Storage using IJSRuntime
try
{
var storedDataJson = await JSRuntime.InvokeAsync<string>("sessionStorage.getItem", "sessionData");
if (!string.IsNullOrEmpty(storedDataJson))
{
sessionData = JsonSerializer.Deserialize<List<FormData>>(storedDataJson);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error loading from Session Storage: {ex.Message}");
}
}
返回null,因为当你执行它时,组件还没有渲染,所以无法访问浏览器。
正如您将其标记为服务器端问题,我假设这是 Blazor 服务器。
有两种选择。
运行
OnAfterRenderASync
中的代码,我不喜欢它,因为你正在改变组件状态并且需要重新渲染才能在 UI 中反映新状态。
在尝试获取值之前执行异步yield。这将使内部组件生命周期代码在尝试检索状态之前进行渲染。您还需要了解服务器预渲染。
这是一个示例页面,它使用
ProtectedSessionStorage
类而不是原始 JSInterop 调用[它为您处理所有序列化],并检测服务器预渲染。有内嵌评论。
@page "/counter"
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@inject IHttpContextAccessor HttpContextAccessor
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<button class="btn btn-primary" @onclick="this.SetSessionData">Set Session Data</button>
<div>
<pre>Session Data: @(_sessionData?.Value ?? "Not Set")</pre>
</div>
@code {
private StorageData? _sessionData = new("-- Not Set --");
protected override async Task OnInitializedAsync()
{
// Detect if we are doing a server side Pre Render. If so use the default value
var isNotServerPreRender = HttpContextAccessor.HttpContext is not null && HttpContextAccessor.HttpContext.Response.HasStarted;
if (isNotServerPreRender)
{
// Do an async Yield to let the first render happen
await Task.Yield();
// We can now interact with JSInterop as the component has rendered
var result = await ProtectedSessionStore.GetAsync<StorageData>("sessionData");
// Get the result Value which will
_sessionData = result.Value;
}
}
private async Task SetSessionData()
=> await ProtectedSessionStore.SetAsync("sessionData", new StorageData($"Set at {DateTime.Now.ToLongTimeString()}"));
public record StorageData(string Value);
}