Angular中如何为ngFor循环内匹配router.url的单个元素加active类
问题根源
你当前定义的active是组件全局的布尔变量,只要遍历到匹配的章节就会将该变量设为true,而所有*ngFor循环生成的.bar元素都绑定了同一个active变量,自然会全部添加上active类。
解决方法
方式一:自行维护匹配逻辑
步骤1:修改TS代码
将全局的active变量替换为存储当前激活章节的slug,匹配到对应章节后直接给该变量赋值即可,同时优化路由匹配逻辑避免子串误匹配:
// 组件内定义变量存储当前激活的章节slug currentActiveSlug: string = ''; // 路由匹配逻辑修改为: for(let i = 0; i < this.chapters.length; ++i) { const targetSlug = this.chapters[i].slug; // 用startsWith代替indexOf,避免出现slug为另一slug子串导致的误匹配 if(this.router.url.startsWith(`/${targetSlug}`)) { this.currentActiveSlug = targetSlug; // 匹配到后直接跳出循环,减少不必要的遍历 break; } }
步骤2:修改模板绑定逻辑
在循环中逐个判断当前章节的slug是否和存储的激活slug一致即可:
<div class="progress-container" > <!-- 把原来的[class.active]="active"替换为下面的判断 --> <div [id]="chapter.slug" class="bar" [class.active]="chapter.slug === currentActiveSlug" [routerLink]="'/'+ chapter.slug" *ngFor="let chapter of chapters; let i = index;"> <div class="fill"></div> <p>{{i + 1}}</p> <div class="question-dots"> <a href="" [routerLink]="'/'+chapter.slug+'/'+question.slug" *ngFor="let question of questions"></a> </div> </div> </div>
方式二:使用Angular内置指令简化逻辑
Angular自带的RouterLinkActive指令可以自动判断当前路由是否和元素绑定的routerLink匹配,自动添加指定类,无需自行编写TS匹配逻辑,直接修改模板即可:
<div class="progress-container" > <!-- 添加routerLinkActive="active"即可,Angular会自动处理激活状态 --> <div [id]="chapter.slug" class="bar" routerLinkActive="active" [routerLink]="'/'+ chapter.slug" *ngFor="let chapter of chapters; let i = index;"> <div class="fill"></div> <p>{{i + 1}}</p> <div class="question-dots"> <a href="" [routerLink]="'/'+chapter.slug+'/'+question.slug" *ngFor="let question of questions"></a> </div> </div> </div>
内容的提问来源于stack exchange,提问作者randomuser12345
相关产品推荐
相关产品推荐

