angular11源码探索二十三[路由forRoot]
forRoot
rotRoot
: 静态方法是配置根路由模块为您的应用程序的方法。调用时RouterModule.forRoot(routes)
,要求AngularRouter
全局实例化该类的实例,Angular创建一个新的基础AppModule
来导入所有功能模块一样,它也提供了AppRoutingModule
导入所有子路径的功能。该forRoot
方法实际上已经在中使用了app-routing.module.ts
。在您的应用中,您只想使用forRoot
一次该方法。这是因为此方法告诉Angular在后台实例化该类的实例Router
,并且您的应用程序中只能有一个路由器,如果您--routing
在创建应用程序时使用参数,则无需担心使用该forRoot
方法,因为它已经为您设置好了
app-routing.module.ts
imports: [RouterModule.forRoot(routes)],
forRoot(routes: Routes, config?: ExtraOptions)
源码位置
这边我们主要探究第二个参数
ExtraOptions
interface ExtraOptions {
// 当为true时,将所有内部导航事件记录到控制台。
// 用于调试导航的事件
enableTracing?: boolean
// 当为true时,启用使用URL片段的# 就是哈希路由
useHash?: boolean
// type InitialNavigation = 'disabled'|'enabled'|'enabledBlocking'|'enabledNonBlocking';
// 默认 enabledNonBlocking 在创建根组件之后开始初始导航。初始导航完成后,引导程序不会被阻止
// 'enabledBlocking'-初始导航在创建根组件之前开始。引导程序将被阻止,直到完成初始导航为止。该值是服务器端渲染正常工作所必需的。
// 'disabled'-不执行初始导航。在创建根组件之前设置位置侦听器。如果由于某种复杂的初始化逻辑,有理由对路由器何时开始其初始导航有更多的控制权,请使用。
// 'enabled' angular 11不推荐使用
initialNavigation?: InitialNavigation
errorHandler?: ErrorHandler
// 预加载策略
preloadingStrategy?: any
// 定义路由器在收到对当前URL的导航请求时应采取的措施
// ignore 默认 这将导致路由器忽略导航
// reload 使用此选项来配置导航到当前URL时的行为,
// 思考了很久,'reload'并不会真正的执行加载工作,它只是重新触发了路由上的events事件循环。
// 这个用意不是很明显, 我发现默认情况下也会触发路由事件,暂时先放放吧
onSameUrlNavigation?: 'reload' | 'ignore'
// 配置向后导航时是否需要恢复滚动位置
// 'disabled'-(默认)不执行任何操作。滚动位置在导航上保持不变。
// 'top'-在所有导航上将滚动位置设置为x = 0,y = 0。
// 'enabled'-在向后导航时恢复上一个滚动位置,如果提供了导航,则将位置设置为锚点,或者将滚动位置设置为[0,0](正向导航)。此选项将在将来成为默认选项。
//我在angular9学习第5篇讲过
scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'
// 是否滚动到该元素 (锚定滚动)
//'disabled' -不执行任何操作(默认)。
// 'enabled'-滚动到元素。此选项将在将来成为默认选项。
anchorScrolling?: 'disabled' | 'enabled'
// 配置路由器滚动到某个元素时将使用的滚动偏移量。当给定具有x和y位置值的元组时,路由器每次滚动时都会使用该偏移量。给定功能后,路由器每次恢复滚动位置时都会调用该功能。
scrollOffset?: [number, number] | (() => [number, number])
// 定义路由器如何将参数,数据和已解析的数据从父路由合并到子路由
// 默认情况下(“ emptyOnly”),仅继承无路径或无组件路由的父参数
// 设置为“ always”始终启用父参数的无条件继承。
paramsInheritanceStrategy?: 'emptyOnly' | 'always'
//错误处理...这个稍等
malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree
// 定义路由器何时更新浏览器URL
// 默认 deferred 在成功导航后进行更新。如果希望在导航开始时更新URL
// eager 尽早更新URL,可以通过显示带有失败URL的错误消息来处理导航失败
urlUpdateStrategy?: 'deferred' | 'eager'
// 这是本来有个bug,然后修复了,所以设置成了 'corrected'
// 启用错误修复程序,以更正具有空路径的组件中的相对路径
// https://github.com/angular/angular/issues/19290
// 相对导航到被空/无组件路线折断的兄弟姐妹
relativeLinkResolution?: 'legacy' | 'corrected'
}
文档网址
https://angular.io/api/router/ExtraOptions
onSameUrlNavigation
'reload'并不会真正的执行加载工作,它只是重新触发了路由上的events事件循环。
当我们设置了 reload 的时候
在页面上使用,我们发现当在当前路由的时候,点击当前路由的导航不会触发事件
this.router.events.pipe(
filter(v=>v instanceof NavigationEnd)
).subscribe(
res=>console.log(res);
)
但是当我们点击其他路由都会触发当前路由的事件,我想它的用意就是这个
如果我们本来在当前路由,点击当前路由的时候想触发事件的话
那我们需要做的是: 修改防护路由的策略,使其每次点击都会触发,路由守卫
这个跟路由守卫没有关联,试了只会当前进来的时候出发一次
anchorScrolling
锚点滚动
设置
anchorScrolling:enabled
这个社会了就相当于可以在网址上面设置 #add执行锚点,启动描点定位
下面这种方法好像直接可以执行不需要设置
<h1 id="add">add</h1>
<button (click)="clickMethod('add')">++</button>
export class TwoComponent implements OnInit, AfterViewInit, OnChanges {
constructor(
private viewPort:ViewportScroller,
) {}
clickMethod(str: string) {
this.viewPort.scrollToAnchor(str)
}
}
添加平滑效果
html{
scroll-behavior: smooth;
}
paramsInheritanceStrategy
上案例
paramsInheritanceStrategy : 'always'
启用父参数的无条件继承。
{
path: 'a', component: AComponent, children: [
{path:'user',component:CComponent}
]
},
A.html中
<a routerLink="user">11111</a><br>
<a [routerLink]="['user']">122222</a>
当前路由在`/a`上, 两种方式都会跳到 `a/user`
如果不想继承可以写绝对定位
relativeLinkResolution
https://angular.io/api/router/ExtraOptions#relativeLinkResolution
const routes = [
{
path: '',
component: ContainerComponent,
children: [
{ path: 'a', component: AComponent },
{ path: 'b', component: BComponent },
]
}
];
从中ContainerComponent,这将不起作用:
<a [routerLink]="['./a']">Link to A</a>
但是,这将起作用:
<a [routerLink]="['../a']">Link to A</a>
换句话说,您需要使用../而不是./。
v11中的默认值为corrected。
forChild
forChild: 当您使用forChild
静态方法时,Router
应用程序中已有一个实例,因此请向该实例注册所有这些路由
注意forChild
上面方法的使用。由于您已经使用了该forRoot
方法,因此只想注册到已实例化的应用路由器的路由
preloadingStrategy
预加载策略
-
NoPreloading-不预加载任何模块,这是默认行为
-
PreloadAllModules-所有模块都尽可能快地预加载
参考
angular9 的学习九
它的目标就是,如果我们很多模块都是懒加载,但是其中有些需要预先加载,可以这样使用
ViewportScroller
源码angular-master/packages/common/src/viewport_scroller.ts
定义滚动位置管理器
在angular9学习八也写到过
abstract class ViewportScroller {
// 配置滚动到锚点时使用的顶部偏移量。
abstract setOffset(offset: [number, number] | (() => [number, number])): void
// 检索当前滚动位置。
abstract getScrollPosition(): [number, number]
// 滚动到指定位置。
abstract scrollToPosition(position: [number, number]): void
// 滚动到锚点元素。
abstract scrollToAnchor(anchor: string): void
// 禁用浏览器提供的自动滚动恢复
abstract setHistoryScrollRestoration(scrollRestoration: "auto" | "manual"): void
}
setOffset()
配置滚动到锚点时使用的顶部偏移量。
[x,y]
clickMethod() {
this.viewport.setOffset([0,1000])
this.viewport.scrollToAnchor('ddd')
}
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬