I started out with the new ASP.NET core web app and the blazor client-side template (3.0.0-preview4-19216-03
).
To add state to the existing Counter.razor
page, I added the following class:
public class GlobalCounter
{
private int _count;
public int Count
{
get => _count;
set
{
if (_count == value) return;
_count = value;
CounterChanged.Invoke(this, new CounterChangedEventArgs(_count));
}
}
public GlobalCounter(int initialCount = 0)
{
_count = initialCount;
}
public event EventHandler<CounterChangedEventArgs> CounterChanged;
}
public class CounterChangedEventArgs : EventArgs
{
public int Count { get; }
public CounterChangedEventArgs(int count)
{
Count = count;
}
}
Within Startup.cs
added following to the ConfigureServices method:
public void ConfigureServices(IServiceCollection services)
{
var counter = new GlobalCounter();
services.AddSingleton(counter);
}
Next I added the singleton to be injected into the Counter.razor
page:
@inject GlobalCounter _counter;
Also added the following code to the @functions
of the page:
protected override async Task OnInitAsync()
{
currentCount = _counter.Count;
_counter.CounterChanged += CounterChanged;
await Task.CompletedTask;
}
void CounterChanged(object sender, CounterChangedEventArgs args)
{
currentCount = args.Count;
}
void IncrementCount()
{
_counter.Count++;
}
Until now it works as expected, leaving the page or reloading will keep the old count.
Next, I adjusted the index.razor to inject the counter and display the count clicked.
@page "/"
@inject GlobalCounter _counter;
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
You pressed the counter @totalCount times.
@functions {
private int totalCount = 0;
protected override async Task OnInitAsync()
{
totalCount = _counter.Count;
_counter.CounterChanged += CounterChanged;
await Task.CompletedTask;
}
void CounterChanged(object sender, CounterChangedEventArgs args)
{
totalCount = args.Count;
}
}
This also works as expected. Pressing the "click me" button on the Counter page and navigating back to the index page, will show the correct count.
Here comes my issue, as soon as I add the <Counter />
page as a component within the index.razor
, pressing the "click me" button will update the count within the component but not the text displayed on the index page.
Is there an explicit call needed to rerender dependent components or some specific binding between pages?
A page is reloaded/refreshed automatically at a specified interval using “NavigationManager” in OnAfterRender() method. Here the NavigateTo(“url”, forceLoad: true) method, is used to force load the browser based on the URI.
To force a component to rerender, use the “StateHasChanged” method in Blazor, to notify that the state has been changed and requires re-rendering.
By using Blazor route parameters, you can pass values from one page to another page. Use NavigationManager to pass a value and route the parameter to another page. Follow this example to achieve passing values from one page to another. Get the passed Page1 parameter value in Page2.
Use the @inject directive to inject the service into components. @inject has two parameters (type and name). Type represents the service type and name represents the service instance name.
Try this in index.razor:
void CounterChanged(object sender, CounterChangedEventArgs args)
{
totalCount = args.Count;
StateHasChanged();
}
You've got to tell Blazor that the state of the component has changed and that she should rerender.
Incidentally, the value in the Counter component is automatically updated because the StateHasChanged method is called by Blazor after the "Click me" button's click event is triggered. StateHasChanged method is automatically called after events of any event type are raised...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With