对大型Blazor应用进行少量更改

时间:2019-05-21 00:10:54

标签: asp.net-core razor blazor

这是我曾提出过类似问题的后续措施,但这一次下面是一个可行的例子。此应用重新渲染/重新计算整个应用,即使只有一小部分需要更新。

打开控制台以查看结果。目的是减少"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>

1 个答案:

答案 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); }
    }