🌐 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
title: 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
```cshtml title="Pages/Edit.razor"
<h3>Edit</h3>
```
```csharp title="Pages/Edit.razor.cs"
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:
```cshtml title="Pages/Edit.razor"
// 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:
```cshtml title="Pages/Edit.razor.cs"
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:
```cshtml title="Pages/Edit.razor"
@page "/edit/{Id:int}"
<h3>Edit</h3>
// highlight-next-line
<div>My paremeter: @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!`.
```cshtml title="Pages/RouteParameter.razor"
@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`.
```cshtml title="Pages/RouteParameter.razor"
@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`:
```html
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` ).
```cshtml title="Pages/User.razor"
@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.
```cshtml title="Pages/User.razor"
@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.
```csharp title="PanelBody.cs"
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
```
```cshtml title="Shared/ParameterChild.razor"
<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`.
```cshtml title="Pages/ParameterParent.razor"
@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.
:::
```html
<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.
```cshtml title="Pages/ParameterParent2.razor"
@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:
```html
<ParameterChild Title="@title" />
```
Wrong:
```html
<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:
```html
<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:
```cshtml title="Pages/ParameterParent3.razor"
@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:
```csharp
[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:
```csharp
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
```
After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code.
---
sidebar_position: 4
title: 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
```cshtml title="Pages/Edit.razor"
<h3>Edit</h3>
```
```csharp title="Pages/Edit.razor.cs"
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:
```cshtml title="Pages/Edit.razor"
// 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:
```cshtml title="Pages/Edit.razor.cs"
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:
```cshtml title="Pages/Edit.razor"
@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!`.
```cshtml title="Pages/RouteParameter.razor"
@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`.
```cshtml title="Pages/RouteParameter.razor"
@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`:
```html
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` ).
```cshtml title="Pages/User.razor"
@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.
```cshtml title="Pages/User.razor"
@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.
```csharp title="PanelBody.cs"
public class PanelBody
{
public string? Text { get; set; }
public string? Style { get; set; }
}
```
```cshtml title="Shared/ParameterChild.razor"
<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`.
```cshtml title="Pages/ParameterParent.razor"
@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.
:::
```html
<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.
```cshtml title="Pages/ParameterParent2.razor"
@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:
```html
<ParameterChild Title="@title" />
```
Wrong:
```html
<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:
```html
<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:
```cshtml title="Pages/ParameterParent3.razor"
@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:
```csharp
[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:
```csharp
[Parameter]
public DateTime StartData { get; set; } = DateTime.Now;
```
After the initial assignment of `DateTime.Now`, do not assign a value to `StartData` in code.

Loading…
Cancel
Save