Je crée une petite application Web de réservation de salle et j'aimerais que la page Web soit actualisée à un intervalle donné; c'est-à-dire une minute donnée ou lorsqu'une modification a été apportée à la base de données. J'ai trouvé StateHasChanged();
mais je ne sais pas vraiment comment l'implémenter (Newbie One Kenobi ici!) J'ai essayé de le mettre dans la fonction pour ajouter un rendez-vous au planning:
var result = Service.CreateSchedule(nextSchedule);
if (result)
{
StateHasChanged();
NavigationManager.NavigateTo("/roomzfront/1");
}
Mais j'ai probablement besoin de quelque chose de plus que cela, ou dans un autre endroit du code.
Vous pouvez essayer ci-dessous -
<ul>
@foreach (var booking in Bookings)
{
<li>@booking.BookedRoomNumber</li>
}
</ul>
@functions{
var timer = new Timer(new TimerCallback(_ =>
{
// Code to fetch the data and bind it to the page level variable
// Ex : Bookings = GetBookingsData();
// This line is necessary
this.StateHasChanged();
}), null, 1000, 1000);
}
Voici une autre approche si vous ne souhaitez pas utiliser SignalR ou WebSockets.
J'ai un Timer qui distribue sur un intervalle dans le cadre de mon composant Sprite, pour vous donner un exemple de la façon de le faire:
Le Sprite a une propriété appelée Subscriber
[Parameter]
public ISpriteSubscriber { get; set; }
Le composant ou la page Host est une interface ISpriteSubscriber.
namespace DataJuggler.Blazor.Components.Interfaces
{
#region interface ISpriteSubscriber
/// <summary>
/// This interface is used by the AnimationManager to notifiy callers that a refresh occurred.
/// </summary>
public interface ISpriteSubscriber
{
#region Methods
#region Refresh()
/// <summary>
/// This method will call StateHasChanged to refresh the UI
/// </summary>
void Refresh();
#endregion
#region Register(Sprite sprite)
/// <summary>
/// This method is called by the Sprite to a subscriber so it can register with the subscriber, and
/// receiver events after that.
/// </summary>
void Register(Sprite sprite);
#endregion
#endregion
#region Properties
#region ProgressBar
/// <summary>
/// This is used so the ProgressBar is stored and available to the Subscriber after Registering
/// </summary>
ProgressBar ProgressBar { get; set; }
#endregion
#endregion
}
#endregion
}
Que dans votre code de rasoir pour définir le parent, vous définissez Subscriber = this:
Notez l'intervalle = 50. Cela définit le minuteur pour qu'il s'actualise toutes les 50 millisecondes.
Dans le setter de mon composant Sprite, la première chose que je fais est d'appeler Register avec le parent:
[Parameter]
public ISpriteSubscriber Subscriber
{
get { return subscriber; }
set
{
// set the value
subscriber = value;
// if the value for HasSubscriber is true
if (HasSubscriber)
{
// Register with the Subscriber so they can talk to each other
Subscriber.Register(this);
}
}
}
Ce code se trouve ici sur la page d'index qui héberge le sprite et enregistre le sprite avec le parent:
public void Register(Sprite sprite)
{
// If the Sprite object exists
if (NullHelper.Exists(Sprite))
{
// if this is the RedCar
if (Sprite.Name == "RedCar")
{
// Set the RedCar
RedCar = Sprite;
}
else
{
// Set the WhiteCar
WhiteCar = Sprite;
}
}
}
Maintenant, lorsque mon bouton de départ de course est cliqué, je ne démarre qu'un seul chronomètre, je ne voulais pas que deux chronomètres fonctionnent même si j'ai deux voitures:
public void StartRace()
{
// if both cars exist
if (NullHelper.Exists(RedCar, WhiteCar))
{
// Create a new instance of a 'RandomShuffler' object.
Shuffler = new RandomShuffler(2, 12, 100, 3);
// Start the timer on the RedCar
RedCar.Start();
}
}
Voici la méthode Start du Sprite:
public void Start()
{
this.Timer = new Timer();
this.Timer.Interval = this.interval;
this.Timer.Elapsed += Timer_Elapsed;
this.Timer.Start();
}
Et puis l'événement Timer_Elapsed, appelle l'abonné à actualiser:
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// if a subscriber exists
if (HasSubscriber)
{
// Notify Subscriber
Subscriber.Refresh();
}
}
Maintenant, ma méthode d'actualisation est appelée toutes les 50 millisecondes dans ce cas, et je mets à jour mon interface utilisateur:
public void Refresh()
{
// do your updates
// Update the UI
InvokeAsync(() =>
{
StateHasChanged();
});
}
Si vous voulez voir un exemple fonctionnel complet, clonez ce projet et recherchez dans le dossier des exemples le ProgressBarSample.
https://github.com/DataJuggler/DataJuggler.Blazor.Components
Il y a aussi une vidéo ici si vous voulez regarder: https://youtu.be/frtetHgfdIo
J'ai utilisé cette approche parent/enfant pour plusieurs choses et cela a si bien fonctionné que j'ai écrit un article de blog à ce sujet: tilisation d'interfaces pour communiquer entre les composants Blazor
Je trouve que c'est un bon moyen de parler à d'autres composants ou d'envoyer des données.