Reputation: 1623
I'm trying out the MVVM pattern with ASP.NET Core WebAssembly and therefore built an ASP.NET Core hosted Application. I was trying to use the "INotfiyPropertyChanged" which I did in an UWP application with the same Models and it worked. For learning purpose I wanted to recreate it in an ASP.NET Core Blazor WebAssembly application using the same pattern.
Following problem, while starting the application the "DateTime" should be updated to the current time. Everytime I start the server-application I don't get the time from now like it should, it is always the same time where I first run the app (at 12am).
my code for this page (index.razor) looks like this:
@page "/"
@using ...
<div class="region-top-left">
<p>@clockViewModel.CurrentTime</p> <!-- From here the 12:00 comes -->
</div>
@code
{
ClockViewModel clockViewModel = new ClockViewModel();
ClockModel clockModel = new ClockModel();
protected override Task OnInitializedAsync()
{
clockViewModel.Initialize(clockModel);
return base.OnInitializedAsync();
}
}
The "Initialize" method gets called inside the index.razor and I was expecting that the current date time will be given back. Also tried to create a breakpoint which never got hit ..
public class ClockViewModel : PropertyChangedBase
{
private ClockModel model;
private string currentTime { get; set; }
public string CurrentTime
{
get
{
return currentTime;
}
set
{
if (currentTime != value)
{
currentTime = value;
NotifyPropertyChanged();
}
}
}
internal void Initialize(ClockModel model)
{
this.model = model;
updateTime();
model.PropertyChanged += ModelPropertyChanged;
}
private void ModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(model.CurrentTime))
{
updateTime();
}
}
private void updateTime()
{
CurrentTime = model.CurrentTime.ToString("h:mm");
}
}
Is this the wrong approach to handle the INotifyPropertyChanged inside an web-app?
Upvotes: 1
Views: 5502
Reputation: 777
You can achieve this in client side Blazor, but you have to notify the UI about the changes by calling ComponentBase.StateHasChanged like this:
protected override Task OnInitializedAsync()
{
clockViewModel.Initialize(clockModel);
clockViewModel.PropertyChanged += ViewModelPropertyChanged;
return base.OnInitializedAsync();
}
private void ViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ClockViewModel.CurrentTime))
{
StateHasChanged();
}
}
public void Dispose()
{
clockViewModel.PropertyChanged -= ViewModelPropertyChanged;
}
There is a requirement that the model.CurrentTime is already periodically updated with the client side or server side time. In case that you need to show server side time you have to periodically pull it from a web service or you have to subscribe to time push notifications from the server.
Upvotes: 1
Reputation: 2281
I would say, yes this is the wrong approach. Generally, you would use JavaScript
for something like this. The main thing that you need to understand about Web Applications is that you have a Server
and a Client
. As opposed to UWP where basically everything is handled on the Client
. With this being said, once you get the request from the Server
no more C#
will be processed until you call to the server again. Also, your OnInitializedAsync
is only hit when the application starts.
Upvotes: 0