19.CSS隔离和代码隔离
19.1 代码隔离
- 使用C# partial 关键字,创建一个与razor文件同名,扩展名加.CS的C#类文件,然后把 razor 文件中的 @code 中的代码迁移至 cs 文件中。注意命名空间、泛形参数声明、依赖注入的迁移
19.2 CSS隔离
- 如同前面代码隔离文件一样,我们创建一个组件样式文件,并以 .CSS 为文件名后缀。
- 组件默认的样式文件来自wwwroot文件夹下的app.css样式文件。
- 每个组件都可以有自己独立的CSS样式文件,最终所有组件的CSS样式文件会在项目编绎时生成一个CSS合成样式文件,生成位置在wwwroot目录下,文件名为"Blazor.styles.css"。
所以,在wwwroot目录下的文件app.razor中有这样一行代码:
<link rel="stylesheett" href="Blazor.styles.css">
20.异常处理
20.1.系统默认的处理方式
在布局页面 MainLayout.razor 中,将代表子页面占位符的 @Body 参数,使用 <ErrorBoundary> @Body </ErrorBoundary>
包裹起来。这样,当发生异常时,将在页面的这个区域提示出默认错误信息:黄色三角中一个叹号、红色背景白色文字:"An error has occurred."。
20.2.自定义异常处理
在 ErrorBoundary 组件中放置 ErrorContent 组件,它后面再放置被ChildContent包裹的 @Body 参数, MainLayout.razor 代码如下:
@inherits LayoutComponentBase
<article class="content px-4">
<ErrorBoundary>
<ErrorContent>
发生异常,消息:@content.Message
</ErrorContent>
<ChildContent>
@Body
</ChildContent>
</ErrorErrorBoundary>
</article>
说明:ErrorContent 组件中有代表异常上下文的C#对象@content可以使用,它的属性 Message,InnerException,Data,Source等。
21. NET8中的流式渲染
21.1 历史遗留的负面包袱
以.NET8之前,如果我们有这样一段代码:
Home.razor
@page "Home"
<p> Count:@count </p>
@code
{
int count = 0;
async Task DoCountAsync()
{
for(int i=0;i<5;i++)
{
await Task.Delay(1000);
count++;
StateHasChanged();
}
}
protected override async OnInitializedAsync()
{
await DoCountAsync();
}
}
该代码表示一个共5秒每秒自增1的计数器,但是实现页面渲染效果却是页面会卡住5秒,5秒后才渲染。如果从命令行用crul https://localhost/Home
来请求该页面,则明显观察到,当回键执行命令后,命领行界面5秒内没有结果,5秒后显示出一屏html的请求结果。
然后,为了解决这个问题在 .NET8之前,我们的做法是,把上面await DoCountAsync();
执行代码从生命周期方法OnInitializedAsync
放入生命周期方法OnAfterRenderAsync(bool firstRender)
中,代码如下:
protected override async OnAfterRenderAsync(bool firstRender)
{
if(firstRender)
await DoCountAsync();
}
当相于,先把页面所有元素渲染出来(包含可能其他前前后后众多的元素),然后才轮到响应OnAfterRenderAsyn生命周期方法,才开始处理计数器逻辑并重新渲染计数器部分的页面。
负面影响:当页面元素较多,渲染任务繁重时,计数器部分的执行要等待所有页面元素的渲染完成,会有巨大延迟。
21.2 流式渲染出场
- 设计思想:
在页面元素从上至下的渲染过程中,遇到动态刷新的部分,则先把动态刷新的部分执行并渲染完毕,再执行该部分的后面的元素的渲染任务。达到,依然是自上而下的流式渲染过程。 - 方法:
1.在页面增加流式渲染指令支持@attribute [StreamRedering]
2.await DoCountAsync();
执行代码依然方在生命周期方法OnInitializedAsync
中
3.流式渲染模式并不要求页面启用交互呈现模式,即使是静态页面也能达成目标。
4.从命令行调用获取页面,返回的结果如下: