AspNetCore.Docs/aspnetcore/blazor/includes/state-container.md

120 lines
3.0 KiB
Markdown
Raw Normal View History

---
2021-05-02 07:03:18 +08:00
no-loc: [Kestrel, appsettings.json, "ASP.NET Core Identity", cookie, Cookie, Blazor, "Blazor Server", "Blazor WebAssembly", "Identity", "Let's Encrypt", Razor, SignalR]
---
Nested components typically bind data using *chained bind* as described in <xref:blazor/components/data-binding>. Nested and un-nested components can share access to data using a registered in-memory state container. A custom state container class can use an assignable <xref:System.Action> to notify components in different parts of the app of state changes. In the following example:
* A pair of components uses a state container to track a property.
* One component in the following example is nested in the other component, but nesting isn't required for this approach to work.
`StateContainer.cs`:
```csharp
using System;
public class StateContainer
{
private string savedString;
public string Property
{
get => savedString;
set
{
savedString = value;
NotifyStateChanged();
}
}
public event Action OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
```
In `Program.Main` (Blazor WebAssembly):
```csharp
builder.Services.AddSingleton<StateContainer>();
```
In `Startup.ConfigureServices` (Blazor Server):
```csharp
services.AddScoped<StateContainer>();
```
`Shared/Nested.razor`:
```razor
@inject StateContainer StateContainer
@implements IDisposable
<h2>Nested component</h2>
<p>Nested component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the Nested component
</button>
</p>
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property =
$"New value set in the Nested component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
```
`Pages/StateContainer.razor`:
```razor
@page "/state-container"
@inject StateContainer StateContainer
@implements IDisposable
<h1>State Container component</h1>
<p>State Container component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the State Container component
</button>
</p>
<Nested />
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property =
$"New value set in the State Container component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
```
2021-02-09 21:04:07 +08:00
The preceding components implement <xref:System.IDisposable>, and the `OnChange` delegates are unsubscribed in the `Dispose` methods, which are called by the framework when the components are disposed. For more information, see <xref:blazor/components/lifecycle#component-disposal-with-idisposable>.