如果您不想使用 SignalR 或 WebSockets,这是另一种方法。
我有一个 Timer 作为我的 Sprite 组件的一部分按间隔调度,给你一个例子来说明如何做到这一点:
Sprite 有一个名为 Subscriber 的属性
[Parameter]
public ISpriteSubscriber { get; set; }
宿主组件或页面是一个 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
}
比在你的剃刀代码中设置父级,你设置 Subscriber=this:
注意间隔=50。这会将计时器设置为每 50 毫秒刷新一次。
在我的 Sprite 组件的 setter 中,我做的第一件事是向父级调用 Register:
[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);
}
}
}
这里的代码在托管精灵的索引页面上,并将精灵注册到父级:
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;
}
}
}
现在,当我点击开始比赛按钮时,我只启动了 1 个计时器,即使我有两辆车,我也不希望两个计时器运行:
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();
}
}
这里是 Sprite 的 Start 方法:
public void Start()
{
this.Timer = new Timer();
this.Timer.Interval = this.interval;
this.Timer.Elapsed += Timer_Elapsed;
this.Timer.Start();
}
然后Timer_Elapsed事件,调用Subscriber刷新:
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// if a subscriber exists
if (HasSubscriber)
{
// Notify Subscriber
Subscriber.Refresh();
}
}
现在在这种情况下,我的刷新方法每 50 毫秒调用一次,然后我更新我的 UI:
public void Refresh()
{
// do your updates
// Update the UI
InvokeAsync(() =>
{
StateHasChanged();
});
}
如果您想查看完整的工作示例,请克隆此项目并在示例文件夹中查找 ProgressBarSample。
https://github.com/DataJuggler/DataJuggler.Blazor.Components
如果您想观看,这里还有一个视频:
https://youtu.be/frtetHgfdIo
我已经在一些事情上使用了这种父/子方法,并且效果很好,我写了一篇关于它的博客文章:Using Interfaces To Communicate Between Blazor Components
我发现这是与其他组件通信或发送数据的好方法。