angular11源码探索二十三[路由forRoot]

forRoot

rotRoot: 静态方法是配置根路由模块为您的应用程序的方法。调用时RouterModule.forRoot(routes),要求AngularRouter全局实例化该类的实例,Angular建立一个新的基础AppModule来导入全部功能模块同样,它也提供了AppRoutingModule导入全部子路径的功能。该forRoot方法实际上已经在中使用了app-routing.module.ts。在您的应用中,您只想使用forRoot一次该方法。这是由于此方法告诉Angular在后台实例化该类的实例Router,而且您的应用程序中只能有一个路由器,若是您--routing在建立应用程序时使用参数,则无需担忧使用该forRoot方法,由于它已经为您设置好了html

app-routing.module.tsgit

imports: [RouterModule.forRoot(routes)],
forRoot(routes: Routes, config?: ExtraOptions)

源码位置github

这边咱们主要探究第二个参数api

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应用程序中已有一个实例,所以请向该实例注册全部这些路由app

注意forChild上面方法的使用。因为您已经使用了该forRoot方法,所以只想注册到已实例化的应用路由器的路由学习

preloadingStrategy

预加载策略this

  • NoPreloading-不预加载任何模块,这是默认行为url

  • 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')
  }

相关文章
相关标签/搜索