11 KiB
sidebar_position | title |
---|---|
4 | Creation of page editor |
Creation of the page
As before, create a new page which will be named Edit.razor
and the partial class Edit.razor.cs
.
Final source code
<h3>Edit</h3>
public partial class Edit
{
}
Set page url
We are going to define the url of our page by specifying that we want our identifier.
Open the Pages/Edit.razor
file and add the highlighted edits as follows:
// highlight-next-line
@page "/edit/{Id:int}"
<h3>Edit</h3>
Pass a parameter
We passed in the url the id of our item to edit, now we are going to retrieve it in a Parameter
in order to be able to use it in our code.
Open the Pages/Edit.razor.cs
file and add the highlighted edits as follows:
public partial class Edit
{
[Parameter]
public int Id { get; set; }
}
View Parameter
In order to verify the passage of our identifier we will display it.
Open the Pages/Edit.razor
file and add the highlighted edits as follows:
@page "/edit/{Id:int}"
<h3>Edit</h3>
// highlight-next-line
<div>My parameter: @Id</div>
Concept: URL parameters
Route settings
The router uses routing parameters to populate corresponding component parameters with the same name.
Route parameter names are case insensitive. In the following example, the text
parameter assigns the value of the road segment to the component's Text
property.
When a request is made for /RouteParameter/amazing
, the <h1>
tag content is rendered as Blazor is amazing!
.
@page "/RouteParameter/{text}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
}
Optional parameters are supported.
In the following example, the optional text
parameter assigns the value of the route segment to the component's Text
property. If the segment is not present, the value of Text
is set to fantastic
.
@page "/RouteParameter/{text?}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string? Text { get; set; }
protected override void OnInitialized()
{
Text = Text ?? "fantastic";
}
}
Use OnParametersSet OnInitialized{Async}
instead to allow navigation to the same component with a different optional parameter value.
Based on the previous example, use OnParametersSet
when the user needs to navigate from /RouteParameter
to /RouteParameter/amazing
or from /RouteParameter/amazing
to /RouteParameter
:
protected override void OnParametersSet()
{
Text = Text ?? "fantastic";
}
Route Constraints
A route constraint applies type matching on a route segment to a component.
In the following example, the route to the User
component matches only if:
- A routing
Id
segment is present in the request URL. - The
Id
segment is an integer type (int
).
@page "/user/{Id:int}"
<h1>User Id: @Id</h1>
@code {
[Parameter]
public int Id { get; set; }
}
The route constraints shown in the following table are available. For more information about route constraints that correspond to the indifferent culture, see the disclaimer below the table.
Constraint | Example | Matching examples | Invariant culture correspondence |
---|---|---|---|
bool |
{active:bool} |
true , FALSE |
No |
datetime |
{dob:datetime} |
2016-12-31 , 2016-12-31 7:32pm |
Yes |
decimal |
{price:decimal} |
49.99 , -1,000.01 |
Yes |
double |
{weight:double} |
1.234 , -1,001.01e8 |
Yes |
float |
{weight:float} |
1.234, -1 ,001.01e8 |
Yes |
guid |
{id:guid} |
CD2C1638-1638-72D5-1638-DEADBEEF1638 , {CD2C1638-1638-72D5-1638-DEADBEEF1638} |
No |
int |
{id:int} |
123456789 , -123456789 |
Yes |
long |
{ticks:long} |
123456789 , -123456789 |
Yes |
:::caution
Routing constraints that check that the URL can be converted to a CLR type (like int
or DateTime
) always use the invariant culture. these constraints assume that the URL is not localizable.
:::
Route constraints also work with optional parameters. In the following example, Id
is required, but Option
is an optional boolean route parameter.
@page "/user/{Id:int}/{Option:bool?}"
<p>
Id: @Id
</p>
<p>
Option: @Option
</p>
@code {
[Parameter]
public int Id { get; set; }
[Parameter]
public bool Option { get; set; }
}
Concept: Component Parameters
Component parameters pass data to components and are set using Public C# Properties on the component class with the [Parameter]
attribute.
In the following example, a built-in reference type ( System.String
) and a user-defined reference type ( PanelBody
) are passed as component parameters.
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
<div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style">
@Body.Text
</div>
</div>
@code {
[Parameter]
public string Title { get; set; } = "Set By Child";
[Parameter]
public PanelBody Body { get; set; } =
new()
{
Text = "Set by child.",
Style = "normal"
};
}
:::caution Providing initial values for component parameters is supported, but does not create a component that writes to its own parameters after the component is first rendered. :::
The Title
& Body
component and ParameterChild
component parameters are defined by arguments in the HTML tag that renders the component instance.
The following ParameterParent
component renders two ParameterChild
components:
- The first
ParameterChild
component is rendered without providing any parameter arguments. - The second
ParameterChild
component receives values forTitle
andBody
from theParameterParent
component, which uses an explicit C# expression to set the values for the properties ofPanelBody
.
@page "/parameter-parent"
<h1>Child component (without attribute values)</h1>
<ParameterChild />
<h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent" Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" />
The following rendered HTML markup of the ParameterParent
component shows default ParameterChild
values for components when the ParameterParent
component does not provide component parameter values.
When the ParameterParent
component provides component parameter values, they override the component's default ParameterChild
values.
:::note For clarity, rendered CSS style classes are not shown in the following rendered HTML markup. :::
<h1>Child component (without attribute values)</h1>
<div>
<div>Set By Child</div>
<div>Set by child.</div>
</div>
<h1>Child component (with attribute values)</h1>
<div>
<div>Set by Parent</div>
<div>Set by parent.</div>
</div>
Assign a C# field, property, or result of a method to a component parameter as an HTML attribute value using the @
symbol.
The following ParameterParent2
component displays four instances of the preceding ParameterChild
component and sets their parameter Title
values to:
- Value of the
title
field. - Result of C#
GetTitle
method. - Current local date in long format with
ToLongDateString
, which uses an implicit C# expression. panelData
Property of theTitle
object.
@page "/parameter-parent-2"
<ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" />
@code {
private string title = "From Parent field";
private PanelData panelData = new();
private string GetTitle()
{
return "From Parent method";
}
private class PanelData
{
public string Title { get; set; } = "From Parent object";
}
}
:::info
When assigning a C# member to a component parameter, prefix the member with the @
symbol and never prefix the parameter's HTML attribute.
Correct use:
<ParameterChild Title="@title" />
Wrong:
<ParameterChild @Title="title" />
:::
Using an explicit Razor expression to concatenate text with an expression result for assignment to a parameter is not supported.
The following example attempts to concatenate the text "Set by" with the property value of an object. The following Razor syntax is not supported:
<ParameterChild Title="Set by @(panelData.Title)" />
The code in the previous example generates a Compiler Error when building the application:
Les attributs de composant ne prennent pas en charge le contenu complexe (mixte C# et balisage).
To support assigning a compound value, use a method, field, or property. The following example performs the concatenation of "Set by
" and the property value of an object in the C# GetTitle
method:
@page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" />
@code {
private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData
{
public string Title { get; set; } = "Parent";
}
}
Component parameters must be declared as Automatic Properties, which means they must not contain custom logic in their get
or set
accessors.
For example, the following StartData
property is an automatic property:
[Parameter]
public DateTime StartData { get; set; }
Do not put custom logic in the get
or set
accessor, as component parameters are purely for use as a channel from a parent component to pass information to a child component.
If a set
accessor of a child component property contains logic that causes the parent component to be re-rendered, the results of an infinite render loop.
To transform a received parameter value:
- Leave the parameter property as auto property to represent the raw data provided.
- Create another property or method to provide the transformed data based on the parameter property.
Override OnParametersSetAsync
to transform a received parameter each time new data is received.
Writing an initial value to a component parameter is supported because initial value assignments don't interfere with automatic component Blazor rendering.
The following assignment of the current locale DateTime
with DateTime.Now
to StartData
is valid syntax in a component:
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
After the initial assignment of DateTime.Now
, do not assign a value to StartData
in code.