You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: aspnetcore/blazor/components.md
+99-3Lines changed: 99 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,13 +5,13 @@ description: Learn how to create and use Razor components, including how to bind
5
5
monikerRange: '>= aspnetcore-3.1'
6
6
ms.author: riande
7
7
ms.custom: mvc
8
-
ms.date: 03/25/2020
8
+
ms.date: 04/21/2020
9
9
no-loc: [Blazor, SignalR]
10
10
uid: blazor/components
11
11
---
12
12
# Create and use ASP.NET Core Razor components
13
13
14
-
By [Luke Latham](https://github.com/guardrex) and [Daniel Roth](https://github.com/danroth27)
14
+
By [Luke Latham](https://github.com/guardrex), [Daniel Roth](https://github.com/danroth27), and [Tobias Bartsch](https://www.aveo-solutions.com/)
15
15
16
16
[View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/master/aspnetcore/blazor/common/samples/) ([how to download](xref:index#how-to-download-a-sample))
17
17
@@ -134,6 +134,9 @@ In the following example from the sample app, the `ParentComponent` sets the val
> Don't create components that write to their own *component parameters*, use a private field instead. For more information, see the [Don't create components that write to their own parameter properties](#dont-create-components-that-write-to-their-own-parameter-properties) section.
139
+
137
140
## Child content
138
141
139
142
Components can set the content of another component. The assigning component provides the content between the tags that specify the receiving component.
@@ -392,7 +395,7 @@ Consider the following example:
392
395
393
396
The contents of the `People` collection may change with inserted, deleted, or re-ordered entries. When the component rerenders, the `<DetailsEditor>` component may change to receive different `Details` parameter values. This may cause more complex rerendering than expected. In some cases, rerendering can lead to visible behavior differences, such as lost element focus.
394
397
395
-
The mapping process can be controlled with the `@key` directive attribute. `@key` causes the diffing algorithm to guarantee preservation of elements or components based on the key's value:
398
+
The mapping process can be controlled with the [`@key`](xref:mvc/views/razor#key) directive attribute. `@key` causes the diffing algorithm to guarantee preservation of elements or components based on the key's value:
396
399
397
400
```csharp
398
401
@foreach (varpersoninPeople)
@@ -446,6 +449,99 @@ Generally, it makes sense to supply one of the following kinds of value for `@ke
446
449
447
450
Ensure that values used for `@key` don't clash. If clashing values are detected within the same parent element, Blazor throws an exception because it can't deterministically map old elements or components to new elements or components. Only use distinct values, such as object instances or primary key values.
448
451
452
+
## Don't create components that write to their own parameter properties
453
+
454
+
Parameters are overwritten under the following conditions:
455
+
456
+
* A child component's content is rendered with a `RenderFragment`.
457
+
*<xref:Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged%2A> is called in the parent component.
458
+
459
+
Parameters are reset because the parent component rerenders when <xref:Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged%2A> is called and new parameter values are supplied to the child component.
460
+
461
+
Consider the following `Expander` component that:
462
+
463
+
* Renders child content.
464
+
* Toggles showing child content with a component parameter.
465
+
466
+
```razor
467
+
<div @onclick="@Toggle">
468
+
Toggle (Expanded = @Expanded)
469
+
470
+
@if (Expanded)
471
+
{
472
+
@ChildContent
473
+
}
474
+
</div>
475
+
476
+
@code {
477
+
[Parameter]
478
+
public bool Expanded { get; set; }
479
+
480
+
[Parameter]
481
+
public RenderFragment ChildContent { get; set; }
482
+
483
+
private void Toggle()
484
+
{
485
+
Expanded = !Expanded;
486
+
}
487
+
}
488
+
```
489
+
490
+
The `Expander` component is added to a parent component that may call `StateHasChanged`:
491
+
492
+
```razor
493
+
<Expander Expanded="true">
494
+
<h1>Hello, world!</h1>
495
+
</Expander>
496
+
497
+
<Expander Expanded="true" />
498
+
499
+
<button @onclick="@(() => StateHasChanged())">
500
+
Call StateHasChanged
501
+
</button>
502
+
```
503
+
504
+
Initially, the `Expander` components behave independently when their `Expanded` properties are toggled. The child components maintain their states as expected. When `StateHasChanged` is called in the parent, the `Expanded` parameter of the first child component is reset back to its initial value (`true`). The second `Expander` component's `Expanded` value isn't reset because no child content is rendered in the second component.
505
+
506
+
To maintain state in the preceding scenario, use a *private field* in the `Expander` component to maintain its toggled state.
507
+
508
+
The following `Expander` component:
509
+
510
+
* Accepts the `Expanded` component parameter value from the parent.
511
+
* Assigns the component parameter value to a *private field* (`_expanded`) in the [OnInitialized event](xref:blazor/lifecycle#component-initialization-methods).
512
+
* Uses the private field to maintain its internal toggle state.
513
+
514
+
```razor
515
+
<div @onclick="@Toggle">
516
+
Toggle (Expanded = @_expanded)
517
+
518
+
@if (_expanded)
519
+
{
520
+
@ChildContent
521
+
}
522
+
</div>
523
+
524
+
@code {
525
+
[Parameter]
526
+
public bool Expanded { get; set; }
527
+
528
+
[Parameter]
529
+
public RenderFragment ChildContent { get; set; }
530
+
531
+
private bool _expanded;
532
+
533
+
protected override void OnInitialized()
534
+
{
535
+
_expanded = Expanded;
536
+
}
537
+
538
+
private void Toggle()
539
+
{
540
+
_expanded = !_expanded;
541
+
}
542
+
}
543
+
```
544
+
449
545
## Partial class support
450
546
451
547
Razor components are generated as partial classes. Razor components are authored using either of the following approaches:
Copy file name to clipboardExpand all lines: aspnetcore/blazor/lifecycle.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,7 +5,7 @@ description: Learn how to use Razor component lifecycle methods in ASP.NET Core
5
5
monikerRange: '>= aspnetcore-3.1'
6
6
ms.author: riande
7
7
ms.custom: mvc
8
-
ms.date: 03/17/2020
8
+
ms.date: 04/16/2020
9
9
no-loc: [Blazor, SignalR]
10
10
uid: blazor/lifecycle
11
11
---
@@ -205,7 +205,7 @@ For information on handling errors during lifecycle method execution, see <xref:
205
205
206
206
## Stateful reconnection after prerendering
207
207
208
-
In a Blazor Server app when `RenderMode` is `ServerPrerendered`, the component is initially rendered statically as part of the page. Once the browser establishes a connection back to the server, the component is rendered *again*, and the component is now interactive. If the [OnInitialized{Async}](xref:blazor/lifecycle#component-initialization-methods) lifecycle method for initializing the component is present, the method is executed *twice*:
208
+
In a Blazor Server app when `RenderMode` is `ServerPrerendered`, the component is initially rendered statically as part of the page. Once the browser establishes a connection back to the server, the component is rendered *again*, and the component is now interactive. If the [OnInitialized{Async}](#component-initialization-methods) lifecycle method for initializing the component is present, the method is executed *twice*:
209
209
210
210
* When the component is prerendered statically.
211
211
* After the server connection has been established.
Copy file name to clipboardExpand all lines: aspnetcore/fundamentals/logging/index.md
+17Lines changed: 17 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -159,6 +159,23 @@ If you need to configure a service that depends on `ILogger<T>`, you can still d
159
159
160
160
The preceding highlighted code is a `Func` that runs the first time the DI container needs to construct an instance of `MyService`. You can access any of the registered services in this way.
161
161
162
+
### Create logs in Blazor WebAssembly
163
+
164
+
Configure logging in Blazor WebAssembly apps with the `WebAssemblyHostBuilder.Logging` property in `Program.Main`:
The `Logging` property is of type <xref:Microsoft.Extensions.Logging.ILoggingBuilder>, so all of the extension methods available on <xref:Microsoft.Extensions.Logging.ILoggingBuilder> are also available on `Logging`.
178
+
162
179
### No asynchronous logger methods
163
180
164
181
Logging should be so fast that it isn't worth the performance cost of asynchronous code. If your logging data store is slow, don't write to it directly. Consider writing the log messages to a fast store initially, then move them to the slow store later. For example, if you're logging to SQL Server, you don't want to do that directly in a `Log` method, since the `Log` methods are synchronous. Instead, synchronously add log messages to an in-memory queue and have a background worker pull the messages out of the queue to do the asynchronous work of pushing data to SQL Server. For more information, see [this](https://github.com/dotnet/AspNetCore.Docs/issues/11801) GitHub issue.
0 commit comments