Marvin's Blog【程式人生】

Ability will never catch up with the demand for it

14 Aug 2021

Blazor University学习笔记【七】

https://blazor-university.com/学习笔记。

Routing

Blazor应用是SPA,改写URL的时候不会是传统的HTTP请求服务端,而是例现化具体的组件进行渲染,然后这个过程可能会与服务端有所交互。

如果改写后的URL也由本类型组件处理,则原组件不会被移除,可直接复用。其命周函数OnInitialized*也不会被调用。

Defining routes

根据组件的RoutingAttribute来给出其路由端点,如下所示:

[Microsoft.AspNetCore.Components.LayoutAttribute(typeof(MainLayout))]
[Microsoft.AspNetCore.Components.RouteAttribute("/")]
public class Index : Microsoft.AspNetCore.Components.ComponentBase
{
}

在razor中则是由@page指示给出的:

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

一个组件可以有多个路由端点,Blazor会通过反射得出所有支持IComponent接口的组件信息。

Route parameters

动态可变的路由端点举例:

@page "/customer/{CustomerId}

想要接收上述路由端点中接收参数,需要定义一个对应的辖属:

@code {
  [Parameter]
  public string CustomerId { get; set; }
}

Constraining route parameters

可以增加额外的constraint作为匹配指标:

@page "/purchase-order/{OrderNumber:int}"

这些匹配指标有本地化的考量。

下列指标尚未支持:

  • Greedy parameters
    • /articles/{Subject}/{*TheRestOfTheURL}
    • 此形式可以匹配斜线
  • Regular expressions
  • Enums
  • Custom constraints

Optional route parameters

可通过指定多个路由端点来达成:

@page "/counter"
@page "/counter/{CurrentCount:int}"

如何设置默认值呢?首先让辖属可以nullable,然后在初始化阶段对参数进行赋值:

[Parameter]
public int? CurrentCount { get; set; }

protected override void OnInitialized()
{
  base.OnInitialized();
  CurrentCount = CurrentCount ?? 1;
}

但是上述技法只在页面首次渲染的时候有效。如果通过URL跳转到页面,则CurrentCount为null,因为组件的一个URL跳转组件的另一个URL不会调用OnInitialized。应对这个问题,需要把使用OnInitialized改为SetParametersAsync:

[Parameter]
public int? CurrentCount { get; set; }

public async override Task SetParametersAsync(ParameterView parameters)
{
  await base.SetParametersAsync(parameters);
  CurrentCount = CurrentCount ?? 1;
}

404 – Not found

Router组件有一个 RenderFragment 参数叫做NotFound,可用于显示Not found页面。

可以使用HTML超链接来进行导览

<a href="/Counter">This works just fine</a>

Blazor包含了一个NavLink组件,用于生成超链接:

<NavLink class="nav-link" href="counter">
  <span class="oi oi-home" aria-hidden="true"></span> Counter
</NavLink>

可以通过ActiveClass来指定鼠标悬停时候的CSS类,默认是active。另一个特殊的参数是Match,用于指定如何匹配URL,以及决定是否激活ActiveClass。

Match参数接收的类型是NavLinkMatch。NavLinkMatch.All代表完全匹配。NavLinkMatch.Prefix代表前缀匹配。

NavigationManager为组件提供导览服务。NavigationManager的NavigateTo以及LocationChanged这两个成员比较特别。NavigateTo可以用于跳转到另一个组件,并且会将改写浏览器的URL,将之前的URL存为历史。此外NavigateTo会触发LocationChanged事件,以URL以及为false的IsNavigationIntercepted作为相关的参数。NavigateTo还有一个名为ForceLoad的参数,用于跳过路由系统。

Detecting navigation events

LocationChanged事件参数如下:

public readonly struct LocationChangedEventArgs
{
  public string Location { get; }
  public bool IsNavigationIntercepted { get; }
}

如果不是从NavigationManager.NavigateTo发起的,那么IsNavigationIntercepted一般是true。

另外一点是,NavigationManager是长存的单现例,若朝其订阅了事件,那么组件移除时要取消订阅,否则组件无法被垃圾回收。

(本篇完)

Categories

Tags