🌐 Fix
continuous-integration/drone/push Build is passing Details

master
Julien Riboulet 2 years ago
parent 97fa5ef0fe
commit 2e39213c97

@ -1,365 +1,365 @@
--- ---
sidebar_position: 4 sidebar_position: 4
title: Creation of page editor title: Creation of page editor
--- ---
## Creation of the page ## Creation of the page
As before, create a new page which will be named `Edit.razor` and the partial class `Edit.razor.cs`. As before, create a new page which will be named `Edit.razor` and the partial class `Edit.razor.cs`.
## Final source code ## Final source code
```cshtml title="Pages/Edit.razor" ```cshtml title="Pages/Edit.razor"
<h3>Edit</h3> <h3>Edit</h3>
``` ```
```csharp title="Pages/Edit.razor.cs" ```csharp title="Pages/Edit.razor.cs"
public partial class Edit public partial class Edit
{ {
} }
``` ```
## Set page url ## Set page url
We are going to define the url of our page by specifying that we want our identifier. 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: Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
```cshtml title="Pages/Edit.razor" ```cshtml title="Pages/Edit.razor"
// highlight-next-line // highlight-next-line
@page "/edit/{Id:int}" @page "/edit/{Id:int}"
<h3>Edit</h3> <h3>Edit</h3>
``` ```
## Pass a parameter ## 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. 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: Open the `Pages/Edit.razor.cs` file and add the highlighted edits as follows:
```cshtml title="Pages/Edit.razor.cs" ```cshtml title="Pages/Edit.razor.cs"
public partial class Edit public partial class Edit
{ {
[Parameter] [Parameter]
public int Id { get; set; } public int Id { get; set; }
} }
``` ```
## View Parameter ## View Parameter
In order to verify the passage of our identifier we will display it. 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: Open the `Pages/Edit.razor` file and add the highlighted edits as follows:
```cshtml title="Pages/Edit.razor" ```cshtml title="Pages/Edit.razor"
@page "/edit/{Id:int}" @page "/edit/{Id:int}"
<h3>Edit</h3> <h3>Edit</h3>
// highlight-next-line // highlight-next-line
<div>My paremeter: @Id</div> <div>My parameter: @Id</div>
``` ```
## Concept: URL parameters ## Concept: URL parameters
### Route settings ### Route settings
The router uses routing parameters to populate corresponding component parameters with the same name. 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. 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!`. When a request is made for `/RouteParameter/amazing`, the `<h1>` tag content is rendered as `Blazor is amazing!`.
```cshtml title="Pages/RouteParameter.razor" ```cshtml title="Pages/RouteParameter.razor"
@page "/RouteParameter/{text}" @page "/RouteParameter/{text}"
<h1>Blazor is @Text!</h1> <h1>Blazor is @Text!</h1>
@code { @code {
[Parameter] [Parameter]
public string? Text { get; set; } public string? Text { get; set; }
} }
``` ```
Optional parameters are supported. 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`. 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`.
```cshtml title="Pages/RouteParameter.razor" ```cshtml title="Pages/RouteParameter.razor"
@page "/RouteParameter/{text?}" @page "/RouteParameter/{text?}"
<h1>Blazor is @Text!</h1> <h1>Blazor is @Text!</h1>
@code { @code {
[Parameter] [Parameter]
public string? Text { get; set; } public string? Text { get; set; }
protected override void OnInitialized() protected override void OnInitialized()
{ {
Text = Text ?? "fantastic"; Text = Text ?? "fantastic";
} }
} }
``` ```
Use `OnParametersSet OnInitialized{Async}` instead to allow navigation to the same component with a different optional parameter value. 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`: Based on the previous example, use `OnParametersSet` when the user needs to navigate from `/RouteParameter` to `/RouteParameter/amazing` or from `/RouteParameter/amazing` to `/RouteParameter`:
```html ```html
protected override void OnParametersSet() protected override void OnParametersSet()
{ {
Text = Text ?? "fantastic"; Text = Text ?? "fantastic";
} }
``` ```
### Route Constraints ### Route Constraints
A route constraint applies type matching on a route segment to a component. 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: In the following example, the route to the `User` component matches only if:
* A routing `Id` segment is present in the request URL. * A routing `Id` segment is present in the request URL.
* The `Id` segment is an integer type ( `int` ). * The `Id` segment is an integer type ( `int` ).
```cshtml title="Pages/User.razor" ```cshtml title="Pages/User.razor"
@page "/user/{Id:int}" @page "/user/{Id:int}"
<h1>User Id: @Id</h1> <h1>User Id: @Id</h1>
@code { @code {
[Parameter] [Parameter]
public int Id { get; set; } public int Id { get; set; }
} }
``` ```
The route constraints shown in the following table are available. 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. 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 | Constraint | Example | Matching examples | Invariant culture correspondence
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ----
| `bool` | `{active:bool}` | `true`, FALSE | No | `bool` | `{active:bool}` | `true`, FALSE | No
| `datetime` | `{dob:datetime}` | `2016-12-31`, `2016-12-31 7:32pm` | Yes | `datetime` | `{dob:datetime}` | `2016-12-31`, `2016-12-31 7:32pm` | Yes
| `decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | Yes | `decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | Yes
| `double` | `{weight:double}` | `1.234`, `-1,001.01e8` | Yes | `double` | `{weight:double}` | `1.234`, `-1,001.01e8` | Yes
| `float` | `{weight:float}` | `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 | `guid` | `{id:guid}` | `CD2C1638-1638-72D5-1638-DEADBEEF1638`, `{CD2C1638-1638-72D5-1638-DEADBEEF1638}` | No
| `int` | `{id:int}` | `123456789`, `-123456789` | Yes | `int` | `{id:int}` | `123456789`, `-123456789` | Yes
| `long` | `{ticks:long}` | `123456789`, `-123456789` | Yes | `long` | `{ticks:long}` | `123456789`, `-123456789` | Yes
:::caution :::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. 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. Route constraints also work with optional parameters. In the following example, `Id` is required, but `Option` is an optional boolean route parameter.
```cshtml title="Pages/User.razor" ```cshtml title="Pages/User.razor"
@page "/user/{Id:int}/{Option:bool?}" @page "/user/{Id:int}/{Option:bool?}"
<p> <p>
Id: @Id Id: @Id
</p> </p>
<p> <p>
Option: @Option Option: @Option
</p> </p>
@code { @code {
[Parameter] [Parameter]
public int Id { get; set; } public int Id { get; set; }
[Parameter] [Parameter]
public bool Option { get; set; } public bool Option { get; set; }
} }
``` ```
## Concept: Component Parameters ## Concept: Component Parameters
Component parameters pass data to components and are set using Public C# Properties on the component class with the `[Parameter]` attribute. 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. In the following example, a built-in reference type ( `System.String` ) and a user-defined reference type ( `PanelBody` ) are passed as component parameters.
```csharp title="PanelBody.cs" ```csharp title="PanelBody.cs"
public class PanelBody public class PanelBody
{ {
public string? Text { get; set; } public string? Text { get; set; }
public string? Style { get; set; } public string? Style { get; set; }
} }
``` ```
```cshtml title="Shared/ParameterChild.razor" ```cshtml title="Shared/ParameterChild.razor"
<div class="card w-25" style="margin-bottom:15px"> <div class="card w-25" style="margin-bottom:15px">
<div class="card-header font-weight-bold">@Title</div> <div class="card-header font-weight-bold">@Title</div>
<div class="card-body" style="font-style:@Body.Style"> <div class="card-body" style="font-style:@Body.Style">
@Body.Text @Body.Text
</div> </div>
</div> </div>
@code { @code {
[Parameter] [Parameter]
public string Title { get; set; } = "Set By Child"; public string Title { get; set; } = "Set By Child";
[Parameter] [Parameter]
public PanelBody Body { get; set; } = public PanelBody Body { get; set; } =
new() new()
{ {
Text = "Set by child.", Text = "Set by child.",
Style = "normal" Style = "normal"
}; };
} }
``` ```
:::caution :::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. 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 `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 following `ParameterParent` component renders two `ParameterChild` components:
* The first `ParameterChild` component is rendered without providing any parameter arguments. * 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`. * 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`.
```cshtml title="Pages/ParameterParent.razor" ```cshtml title="Pages/ParameterParent.razor"
@page "/parameter-parent" @page "/parameter-parent"
<h1>Child component (without attribute values)</h1> <h1>Child component (without attribute values)</h1>
<ParameterChild /> <ParameterChild />
<h1>Child component (with attribute values)</h1> <h1>Child component (with attribute values)</h1>
<ParameterChild Title="Set by Parent" Body="@(new PanelBody() { Text = "Set by parent.", Style = "italic" })" /> <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. 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. When the `ParameterParent` component provides component parameter values, they override the component's default `ParameterChild` values.
:::note :::note
For clarity, rendered CSS style classes are not shown in the following rendered HTML markup. For clarity, rendered CSS style classes are not shown in the following rendered HTML markup.
::: :::
```html ```html
<h1>Child component (without attribute values)</h1> <h1>Child component (without attribute values)</h1>
<div> <div>
<div>Set By Child</div> <div>Set By Child</div>
<div>Set by child.</div> <div>Set by child.</div>
</div> </div>
<h1>Child component (with attribute values)</h1> <h1>Child component (with attribute values)</h1>
<div> <div>
<div>Set by Parent</div> <div>Set by Parent</div>
<div>Set by parent.</div> <div>Set by parent.</div>
</div> </div>
``` ```
Assign a C# field, property, or result of a method to a component parameter as an HTML attribute value using the `@` symbol. 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: The following `ParameterParent2` component displays four instances of the preceding `ParameterChild` component and sets their parameter `Title` values to:
* Value of the `title` field. * Value of the `title` field.
* Result of C# `GetTitle` method. * Result of C# `GetTitle` method.
* Current local date in long format with `ToLongDateString`, which uses an implicit C# expression. * Current local date in long format with `ToLongDateString`, which uses an implicit C# expression.
* `panelData` Property of the `Title` object. * `panelData` Property of the `Title` object.
```cshtml title="Pages/ParameterParent2.razor" ```cshtml title="Pages/ParameterParent2.razor"
@page "/parameter-parent-2" @page "/parameter-parent-2"
<ParameterChild Title="@title" /> <ParameterChild Title="@title" />
<ParameterChild Title="@GetTitle()" /> <ParameterChild Title="@GetTitle()" />
<ParameterChild Title="@DateTime.Now.ToLongDateString()" /> <ParameterChild Title="@DateTime.Now.ToLongDateString()" />
<ParameterChild Title="@panelData.Title" /> <ParameterChild Title="@panelData.Title" />
@code { @code {
private string title = "From Parent field"; private string title = "From Parent field";
private PanelData panelData = new(); private PanelData panelData = new();
private string GetTitle() private string GetTitle()
{ {
return "From Parent method"; return "From Parent method";
} }
private class PanelData private class PanelData
{ {
public string Title { get; set; } = "From Parent object"; public string Title { get; set; } = "From Parent object";
} }
} }
``` ```
:::info :::info
When assigning a C# member to a component parameter, prefix the member with the `@` symbol and never prefix the parameter's HTML attribute. 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: Correct use:
```html ```html
<ParameterChild Title="@title" /> <ParameterChild Title="@title" />
``` ```
Wrong: Wrong:
```html ```html
<ParameterChild @Title="title" /> <ParameterChild @Title="title" />
``` ```
::: :::
Using an explicit Razor expression to concatenate text with an expression result for assignment to a parameter is not supported. 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: The following example attempts to concatenate the text "Set by" with the property value of an object. The following Razor syntax is not supported:
```html ```html
<ParameterChild Title="Set by @(panelData.Title)" /> <ParameterChild Title="Set by @(panelData.Title)" />
``` ```
The code in the previous example generates a Compiler Error when building the application: 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). 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: 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:
```cshtml title="Pages/ParameterParent3.razor" ```cshtml title="Pages/ParameterParent3.razor"
@page "/parameter-parent-3" @page "/parameter-parent-3"
<ParameterChild Title="@GetTitle()" /> <ParameterChild Title="@GetTitle()" />
@code { @code {
private PanelData panelData = new(); private PanelData panelData = new();
private string GetTitle() => $"Set by {panelData.Title}"; private string GetTitle() => $"Set by {panelData.Title}";
private class PanelData private class PanelData
{ {
public string Title { get; set; } = "Parent"; 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. 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: For example, the following `StartData` property is an automatic property:
```csharp ```csharp
[Parameter] [Parameter]
public DateTime StartData { get; set; } 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. 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. 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: To transform a received parameter value:
* Leave the parameter property as auto property to represent the raw data provided. * 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. * 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. 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. 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: The following assignment of the current locale `DateTime` with `DateTime.Now` to `StartData` is valid syntax in a component:
```csharp ```csharp
[Parameter] [Parameter]
public DateTime StartData { get; set; } = DateTime.Now; public DateTime StartData { get; set; } = DateTime.Now;
``` ```
After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code. After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code.

Loading…
Cancel
Save