-
Book Overview & Buying
-
Table Of Contents
-
Feedback & Rating
Building Blazor WebAssembly Applications with gRPC
By :
Blazor WebAssembly is a SPA. This means that routing is not done on the server but the client. While clicking on the link updates the address bar of the browser, the page itself is not refreshed. Blazor finds a component with a matching route in the @page directive and renders this component (and all child components) as a page.
The Router component takes care of resolving the correct component to render. This component is typically used in the application root component – that is, App.razor. The component is created from two RenderFragments, as follows:
<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>
In the preceding code, you can see the Router component with the Found and NotFound sections. The Router component looks to the specified AppAssembly and discovers all routable components (components with the @page directive). When navigating from one page to another, the Router component renders the Found section, if there is any routable component with a matched route. Otherwise, the NotFound section is rendered.
Rendering of the component is handled in the RouteView component. The RouteData parameter of the component contains information about the matched component. RouteView uses a layout defined on the component’s @layout directive, or DefaultLayout if the component layout is not specified.
The FocusOnNavigate component is not required. This component sets focus on the element specified by the CSS selector in the Selector parameter. It is useful when building websites compatible with screen readers, or when you want to focus on some user input fields after changing the page.
To navigate between pages, the standard HTML anchor is used:
<a href="/contacts">Contacts</a>
As shown in the preceding code, there is no difference between page navigation in standard HTML and Blazor. That is one of Blazor’s advantages over other JavaScript SPA frameworks, which use the custom component to provide SPA navigation. Blazor intercepts any navigation on the same site and tries to find the corresponding components to render.
If you need to manipulate the address from the C# code, you must inject NavigationManager into your code, as follows:
@page "/offers"
@inject NavigationManager NavManager
…
<button @onclick="GoToContacts">Contacts</button>
@code {
void GoToContacts()
{
NavManager.NavigateTo("contacts");
}
}
The preceding code will change the page to /contacts after the button is clicked.
The @page directive can be specified multiple times in the component. It can also contain dynamic parts of the URL:
PageDirective.razor
@page "/author"
@page "/author/{Name}"
<h1>Author @authorName </h1>
@code {
private string authorName;
[Parameter]
public string Name { get; set; }
protected override void OnInitialized()
{
authorName = Name ?? "Not set";
}
}
In the preceding code, the first @page directive specifies the URL without any parameters. The second @page directive specifies a parameter with the name. The following URLs are valid for the PageDirective component:
/author/author/John/author/123In the third example, /author/123, you can see that we can pass numbers to the text parameter. It is fine here because any value can be treated like a string. But what if we expect a different type?
Route constraints are used when you need to enforce a specific data type of the route parameter. The route constraints are defined the same way as in C# API endpoints – that is, by adding a semicolon after the parameter name and then specifying the data type:
@page "/author/{Id:int}"
The preceding code will define the URL for the author with Id as an integer.
Not all constraints are supported at the time of writing. The following table shows the supported types:
|
Constraint type |
Example of constraint |
Example of valid values |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Table 2.2 – Blazor router supported constraints
Component route parameters can also be marked as optional:
@page "/user/{id:int}/{valid:bool?}"
The preceding code specifies the URL to /user with the required Id parameter and optional Valid bool parameter. The optional ? symbol can also be used without type constraints.
Sometimes, you may need to create components for multiple routes. In that case, a catch-all parameter can be used:
Posts/AllPosts.razor
@page "/posts/{*pageRoute}"
@code {
[Parameter]
public string? PageRoute { get; set; }
}
The preceding code shows a catch-all parameter named PageRoute. The catch-all route parameter must be of the string type and placed at the end of the route; it is not case-sensitive.
The PageRoute parameter will contain all the matched values from the URL:
/posts/animals/africa/forest URL, the PageRoute value is animals/africa/forest/posts/animals URL, the PageRoute value is animals/posts/animals/europa%2Fwater URL, the PageRoute value is animals/europa/waterWith that, we know how to create components and how to navigate between them. In the next section, we will look at the project we will be creating in this book. And yes! We will use everything we’ve learned in this chapter up until this point.
Change the font size
Change margin width
Change background colour