Home > OS >  How to pass a generic object to another page in Blazor?
How to pass a generic object to another page in Blazor?

Time:09-30

I have a component in Blazor that takes a parameter "TItem" which can be any object:

Employees.razor

@page "/Employees"

<GenericGrid TItem="Employee" MaintainState="true"></GenericGrid>

@code
{
  
}

The above component is a wrapper for a Telerik grid component. This way, I can use the same grid component to display data from different objects, depending on which object I pass onto it (Employee, Customer, etc.)

GenericGrid.razor (only showing relevant code)

@typeparam TItem

...grid layout...
<GridToolBar>
       <GridCommandButton Icon="add">New @typeof(TItem).Name</GridCommandButton>
</GridToolBar>
...rest of grid layout...

@code {
    ...

    [Parameter]
    public TItem Entity { get; set; }

    ...

When the button gets clicked, I want to send the user to another page. This page should contain a form for creating whatever object I pass onto it. However, the first obstacle is being able to send the object to another page in the first place. Route parameters only support things like strings and integers, so that's not an option.

I found the following StackOverflow question: c# blazor how to pass a List to a page. The accepted solution looks like a viable option, but I can't wrap my head around how to implement this for my case.

CodePudding user response:

Short version: Don't.

Long version:

Blazor is SPA. You don't need to pass anything to anything else, especially in a route parameter. Literally the only necessary navigation in my entire site (With now maybe a couple hundred Components) is between the MVC scaffolded Identity system (which I hate) and my main page.

If you really NEED to enforce page separation (you don't though), you should pass some kind of IDENTIFIER-- the name of the Type, an enum which represents acceptable types, etc.

If you REALLY REALLY need to maintain an actual object, you can do that through a scoped service, or through a variable in the parent page (probably the layout page) which you Cascade to its children. Don't do any of these. . . but you could. :P

CodePudding user response:

The Simple Solution would be using State. Suppose you have 2 pages Employees & EmployeeDetail pages and you you need to pass employee object from Employees to EmployeeDetail.

AppState.cs

public class AppState
{   
    public Employee Employee { get; set; }
}

public class Employee
{
    public string Name { get; set; }
}

and you need to register AppState as scoped in your program.cs

services.AddScoped<AppState>();

Employees.razor

@page "/employees"
@inject AppState AppState
@inject NavigationManager NavigationManager

<button @onclick="NavigateToEmployeeDetail">Send Employee</button>

@code{
    private void NavigateToEmployeeDetail()
    {
        //set the employee object before navigating
        AppState.Employee = new Employee { Name = "Employee1" };
        NavigationManager.NavigateTo("/employeedetail");
    }
}

EmployeeDetail.razor

@page "/employeedetail"

@inject AppState AppState

<h1>Employee Name :  @EmployeeName</h1>

@code{
    public string EmployeeName { get; set; }
    protected override void OnInitialized()
    {
        if (AppState.Employee is null) return;
        EmployeeName = AppState.Employee.Name;
    }
}
  • Related