这是我曾提出过类似问题的后续措施,但这一次下面是一个可行的例子。此应用重新渲染/重新计算整个应用,即使只有一小部分需要更新。
打开控制台以查看结果。目的是减少"Monstor.Build..."
的打印次数。
@page "/monstor"
@functions {
static int redraw = 0;
static bool doWork = true;
string status = "--";
void HandleEvent(string anEvent) {
status = anEvent; // updates every 2 seconds
StateHasChanged(); // renders MonstrouslyDeepApp--every 2 seconds!
}
async Task work() { // simulate external events
if (doWork) {
doWork = false;
while (true) {
await Task.Delay(2000);
HandleEvent(DateTime.Now.ToLongTimeString());
}
}
}
protected override void OnInit() {
work();
}
void Also_do_monstrous_business_calculations(int x) {
System.Console.WriteLine(" Calculating...");
}
}
@{
Also_do_monstrous_business_calculations(42);
}
<div class="main">
<div class="toolbar row bg-light">
<span style="width:100%;text-align:right"> Status: @status </span>
</div>
<div class="main-app row jumbotron">
<h1>I am Monstor App # @redraw. Fear me!</h1>
@*<MonstrouslyDeepApp M="@ModelRoot" />*@
@{
System.Console.WriteLine($" Monster.Build #{redraw}");
redraw++;
}
</div>
</div>
答案 0 :(得分:0)
这是我解决问题的方法。它有效,但有点令人费解,我希望有人能找到更好的方法...
基本上,我用<Updatable>
包装要隔离更新的区域:
<div class="main">
<Updatable Event="@statusEvent">
<div class="toolbar row bg-light">
<span style="width:100%;text-align:right"> Status: @status </span>
</div>
</Updatable>
:
</div>
您可以这样定义和使用statusEvent
:
@functions {
:
string status = "--";
UpdateEvent statusEvent = new UpdateEvent();
void HandleEvent(string anEvent) {
status = anEvent; // updates every 2 seconds
//StateHasChanged(); // renders MonstrouslyDeepApp--every second!
statusEvent.StateChanged(); // only renders status area--every second
}
:
}
在Updatable.razor中:
@page "/Updatable"
@functions {
[Parameter] UpdateEvent Event { get; set; }
[Parameter] RenderFragment ChildContent { get; set; }
protected override void OnInit() {
Event.OnChange += (s, e) => {
StateHasChanged();
};
}
}
@ChildContent
最后,UpdateEvent仅仅是事件包装器:
public class UpdateEvent {
public event EventHandler OnChange;
public void StateChanged() { OnChange?.Invoke(this, EventArgs.Empty); }
}