blazor 页面没有像应有的那样将 sessionData 加载到 RadzenGrid 中

问题描述 投票:0回答:1

我有一个表单,允许用户填写电子剩余的多个字段。它使用浏览器会话存储存储我在 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 的开发还是很陌生,如果这听起来像是一个菜鸟问题,我很抱歉。任何帮助都会很棒!!!

blazor blazor-server-side form-data radzen
1个回答
0
投票

这段代码:

    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 服务器。

有两种选择。

  1. 运行

    OnAfterRenderASync
    中的代码,我不喜欢它,因为你正在改变组件状态并且需要重新渲染才能在 UI 中反映新状态。

  2. 在尝试获取值之前执行异步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);
}
© www.soinside.com 2019 - 2024. All rights reserved.