如何实现<app-tabs-components>失焦自动隐藏,规避重复调用服务?
解决Tabs组件重复隐藏代码的DRY方案
嘿,这种每个组件都重复写tabService.showHide(false)的情况确实违反了DRY原则,太啰嗦了!我给你几个实用的方案,轻松实现Tabs组件在失去焦点/非活跃状态时自动关闭,再也不用重复写代码啦。
方案一:路由守卫全局处理(适合路由切换场景)
如果你的组件是通过路由加载的,那用路由守卫绝对是最省心的方式——全局配置一次,所有路由切换时自动隐藏Tabs:
- 先创建一个路由守卫:
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { TabService } from './tab.service'; @Injectable({ providedIn: 'root' }) export class HideTabsGuard implements CanActivate { constructor(private tabService: TabService) {} canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { // 每次进入新路由,自动隐藏Tabs this.tabService.showHide(false); return true; } }
- 然后在路由配置里全局应用这个守卫(或者给特定路由添加):
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HideTabsGuard } from './hide-tabs.guard'; const routes: Routes = [ { path: '', canActivate: [HideTabsGuard], // 全局生效 children: [ { path: 'home', component: HomeComponent }, { path: 'profile', component: ProfileComponent }, // 其他路由... ] } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
这样只要路由切换,Tabs就自动隐藏,完全不用在组件里写任何代码!
方案二:自定义指令(适合页面内组件切换场景)
如果你的组件是在同一页面内切换显示(比如tab页、模态框),那自定义一个指令就很合适,给需要的组件加个指令就能自动处理:
- 创建自动隐藏Tabs的指令:
import { Directive, HostListener, OnInit } from '@angular/core'; import { TabService } from './tab.service'; @Directive({ selector: '[appAutoHideTabs]' // 指令选择器 }) export class AutoHideTabsDirective implements OnInit { constructor(private tabService: TabService) {} ngOnInit(): void { // 组件初始化时先隐藏(可选,根据你的需求调整) this.tabService.showHide(false); } // 监听组件失去焦点事件,失去焦点就隐藏Tabs @HostListener('blur') onComponentBlur(): void { this.tabService.showHide(false); } // 如果是基于组件激活状态的,还可以加其他监听,比如自定义的active变化事件 // @HostListener('activeChange', ['$event']) onActiveChange(isActive: boolean) { // if (!isActive) this.tabService.showHide(false); // } }
- 在需要的组件上添加这个指令:
<app-home-component appAutoHideTabs></app-home-component> <app-settings-component appAutoHideTabs></app-settings-component>
这样每个需要自动隐藏Tabs的组件,只需要加个appAutoHideTabs指令就行,代码复用拉满。
方案三:改造TabService自动监听路由
如果你的Tabs显示状态完全和路由绑定,那直接在TabService里监听路由事件更简单,连守卫都不用写:
import { Injectable } from '@angular/core'; import { Router, NavigationEnd } from '@angular/router'; import { filter } from 'rxjs/operators'; @Injectable({ providedIn: "root" }) export class TabService { show = false; constructor(private router: Router) { // 订阅路由导航结束事件,每次路由切换后自动隐藏Tabs this.router.events.pipe( filter(event => event instanceof NavigationEnd) ).subscribe(() => { this.showHide(false); }); } showHide(status: boolean) { this.show = status; } get() { return this.show; } }
这个方案最简洁,TabService自己就能处理路由切换时的隐藏逻辑,组件里完全不用管,彻底贯彻DRY原则!
内容的提问来源于stack exchange,提问作者POV
相关产品推荐
相关产品推荐

