• angular11源码探索十九[路由RouterLinkActive和RouterOutlet]


    routerLinkActive

    链接路由当前是否处于活动状态,并允许您指定一个或多个CSS类

      是否精准查找,例如 默认  /a/b   而当前是 /a 也是匹配的
    @Input() routerLinkActiveOptions: {exact: boolean} = {exact: false};
    

    发现一个RXjs技巧我们以后也可以这样合并使用

      @ContentChildren(RouterLink, {descendants: true}) links!: QueryList<RouterLink>;
      linksWithHrefs!: QueryList<RouterLinkWithHref>;
      ngAfterContentInit(): void {
        // of(null)用于强制订阅主体立即执行一次
        from([this.links.changes, this.linksWithHrefs.changes, of(null)])
            .pipe(mergeAll())
            .subscribe(_ => {
              this.update();
              this.subscribeToEachLinkOnChanges();
            });
      } 
    

    我们更新视图的时候可以使用ChangeDetectorRef 更新

    constructor(
          private readonly cdr: ChangeDetectorRef) {
        this.routerEventsSubscription = router.events.subscribe((s: Event) => {
          if (s instanceof NavigationEnd) {
            this.update();
          }
        });
      }
    
    private update(): void {
    		  .....
            this.cdr.markForCheck();
            this.classes.forEach((c) => {
              if (hasActiveLinks) {
                this.renderer.addClass(this.element.nativeElement, c);
              } else {
                this.renderer.removeClass(this.element.nativeElement, c);
              }
            });
          }
        });
      }
    

    返回的路由是否被激活

    		路由					是否严格查询 
    isActive(url: string|UrlTree, exact: boolean): boolean
    private router:Router
    this.router.isActive('/a/c',true) //boolean
    

    测试案例

    当处于/user/bob 路由的时候,默认选中的状态
    <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
    如果是多个class
     <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
     <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
    
    `exact: true` 是否完全匹配
    <a routerLink="/user/bob" routerLinkActive="active-link" 
    		[routerLinkActiveOptions]="{exact: true}">Bob</a>
    
    拿到选中的状态
    <a routerLink="/" routerLinkActive="active-link" #rla="routerLinkActive">
      *     {{ !!rla.isActive }}
       </a>
    

    RouterOutlet

    路由出口,占位符

      @Output('activate') activateEvents = new EventEmitter<any>();
      @Output('deactivate') deactivateEvents = new EventEmitter<any>();
    拿到默认的name属性的值用于多路由出口用
    export const PRIMARY_OUTLET = 'primary';
    constructor(
          @Attribute('name') name: string) {
        this.name = name || PRIMARY_OUTLET;
      }
    

    我们看到还有四个只读属性

    isActivated: boolean 是否匹配
    component: Object 拿到当前匹配的组件 不包括父路由的
    activatedRoute: ActivatedRoute 这个我感觉直接用ActiveteRouter直接可以啦,无价值
    activatedRouteData: Data 拿到传递路由传递过来的数据
    export class DComponent implements OnInit,AfterViewInit {
    
      constructor(
        private routerOuter:RouterOutlet
    
      ) { }
    
      ngOnInit(): void {
      }
      ngAfterViewInit() {
        console.log(this.routerOuter.isActivated);
        console.log(this.routerOuter.component);
        console.log(this.routerOuter.activatedRouteData);
          //           {path: 'd', component: DComponent,data:{name:'xxx'}}
    		// 拿到data的数据
      }
    }
    

    案例demo

     每有router-outlet 都有唯一的名称,这个用name属性决定的,默认的name为primary
    <router-outlet></router-outlet>
    <router-outlet name='left'></router-outlet>
    <router-outlet name='right'></router-outlet>
    出口用 outlet 属性表示
    {path: <base-path>, component: <component>, outlet: <target_outlet_name>}
    
    	{
            path: 'a', component: AComponent, children: [
              {path: 'd', component: DComponent},
              {path: 'c', component: CComponent,outlet:'right'},
              // a/(d//right:c)
            ]
          },
    
     A html  两个路由别名
     
     导航跳转
     <a [routerLink]="['/a',{outlets:{primary:['d'],right:['c']}}]">d/c</a>
     <p>a works!</p>
    <router-outlet></router-outlet>
    <div style="background-color: red;">
      <router-outlet name="right"></router-outlet>
    </div>
    
    多视口的情况了
    我发现routerLink写会报错,应该用    this.router.navigateByUrl('/user/(jim//aux:team)')
    下面错误
    <a [routerLink]="['/user/(jim//aux:team)']">Jim</a>
    两个视口 一个是 jim
    		一个是 team     aux是编写
                			<router-outlet name='aux'></router-outlet>
            				 {path: 'c', component: CComponent,outlet:'aux'}
    
     <router-outlet
        (activate)='onActivate($event)'
       (deactivate)='onDeactivate($event)'></router-outlet>
    // 当组件被激活的事件
     onActivate($event: any) {
        console.log('激活');
      }
    // 当组件被销毁的事件
      onDeactivate($event: any) {
        console.log('销毁');
      }
    

    多出口的案例

      {
            path: 'a', component: AComponent, children: [
              {path: 'd', component: DComponent,outlet:'left'},
              {path: 'b', component: BComponent},
              {path: 'c', component: CComponent,outlet:'right'}
              // /a/(b//left:d//right:c)
            ]
          }
    a html
    <router-outlet></router-outlet>
    <router-outlet name="left"></router-outlet>
    <router-outlet name="right"></router-outlet>
    
    在查看源码的时候我们看到这样的例子
    /one/three/(two//left:three)(right:four)
    不怎么怎么写都报错,其实他的出口是
                /one/three/(two//left:three)
                (right:four)
    他们的通过出口是以 /为最后的起步,在url_three源码解析我们可以理解到
    
  • 相关阅读:
    两步验证杀手锏:Java 接入 Google 身份验证器实战
    涨姿势:Spring Boot 2.x 启动全过程源码分析
    Spring Cloud 升级最新 Finchley 版本,踩了所有的坑!
    Spring Boot 2.x 启动全过程源码分析(上)入口类剖析
    推荐:7 月份值得一看的 Java 技术干货!
    屌炸天,Oracle 发布了一个全栈虚拟机 GraalVM,支持 Python!
    Spring Boot 核心配置文件 bootstrap & application 详解。
    出场率比较高的一道多线程安全面试题
    凉凉了,Eureka 2.x 停止维护,Spring Cloud 何去何从?
    读写Excel
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14260346.html
Copyright © 2020-2023  润新知