You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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 for Title and Body from the ParameterParent component, which uses an explicit C# expression to set the values for the properties of PanelBody.
@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 the Title 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.