Angular 4动画:为ngFor选中元素单独触发手风琴动画
解决Angular 4手风琴点击所有元素触发动画的问题
兄弟,我太懂你这个痛点了!你现在肯定是用了一个全局的布尔变量(比如isOpen)来控制所有手风琴项的展开/收起状态,所以点任何一个都会触发所有元素的动画。要实现只动点击的那个元素,核心就是给每个手风琴项单独维护展开状态,下面给你一步步来解决:
1. 给每个分类项添加独立的状态存储
首先,你需要为每个tertiaryFilterCategory单独记录它的展开状态。有两种简单的方式:
方式一:给每个分类对象新增属性(直接修改原数据)
如果你的tertiaryFilterCategory是可修改的,可以在初始化数据的时候给每个项加个isExpanded属性:
// 组件类里初始化数据时 this.tertiaryLevelData.groupBy.values.forEach(category => { category.isExpanded = false; // 默认全部收起 });
方式二:用独立对象存储状态(推荐,不污染原数据)
如果不想修改原数据,可以在组件里定义一个对象,用每个分类的唯一标识(比如id、名称)作为key来存状态:
// 组件类里 expandedStates: { [key: string]: boolean } = {}; // 初始化时默认全部收起 ngOnInit() { this.tertiaryLevelData.groupBy.values.forEach(category => { this.expandedStates[category.id] = false; // 假设category有唯一id属性 }); }
2. 修改点击事件,只切换当前项的状态
把点击事件绑定到每个li(或者你说的ul)上,传入当前的分类项,然后切换它对应的状态:
模板里的点击事件
<ul class="each-filter-desc"> <!-- 外层循环 --> <li class="each-filter-options" *ngFor='let tertiaryFilterCategory of tertiaryLevelData.groupBy.values; let k = index' (click)="toggleAccordion(tertiaryFilterCategory)"> <!-- 分类标题 --> <div class="filter-title">{{ tertiaryFilterCategory.name }}</div> <!-- 需要展开/收起的内容,绑定动画 --> <div class="filter-content" [@slideInOut]="getExpandedState(tertiaryFilterCategory)"> <!-- 这里放你的内容区域 --> </div> </li> </ul>
组件类里的切换方法
// 如果用方式一(对象自带属性) toggleAccordion(category: any) { category.isExpanded = !category.isExpanded; } // 如果用方式二(独立状态对象) toggleAccordion(category: any) { this.expandedStates[category.id] = !this.expandedStates[category.id]; } // 可选:如果用方式二,模板里可以用这个方法获取状态(也可以直接写表达式) getExpandedState(category: any) { return this.expandedStates[category.id] || false; }
3. 确保动画绑定到当前项的状态
你的动画触发器(比如@slideInOut)要绑定到当前项的状态,而不是全局变量。比如上面模板里的[@slideInOut]="getExpandedState(tertiaryFilterCategory)"或者[@slideInOut]="tertiaryFilterCategory.isExpanded"。
这里给你一个Angular 4兼容的动画示例,放在组件的animations数组里:
import { trigger, state, style, transition, animate } from '@angular/animations'; @Component({ // ...其他组件配置 animations: [ trigger('slideInOut', [ state('false', style({ height: '0px', opacity: 0, overflow: 'hidden' })), state('true', style({ height: '*', opacity: 1 })), transition('false <=> true', animate('300ms ease-in-out')), ]) ] })
关键注意点
- 一定要避免用全局的
isOpen变量控制所有项,每个项的状态必须独立 - 确保每个分类项有唯一的标识(id、name等),用来区分不同的状态(如果用方式二的话)
- 动画的
state要和你绑定的布尔值对应(Angular 4支持直接绑定布尔值,也可以用字符串形式的'true'/'false')
这样修改之后,点击某个手风琴项就只会触发当前项的展开/收起动画,不会影响其他元素了!
内容的提问来源于stack exchange,提问作者Trinanjan Saha
相关产品推荐
相关产品推荐

