Angular 4中为数组每个元素实现下拉元素的技术求助
解决Angular循环项独立展开/收起的问题
嘿,我一眼就看出你现在遇到的问题啦——你用了一个全局的isShow变量,所有通过*ngFor循环生成的酒店项都会共享这个状态,导致点击任何一个按钮,所有的额外信息都会同时展开或收起。要实现点击对应按钮只展开当前项的额外信息,有两种常用的解决方案:
方案一:给每个酒店对象添加独立的状态属性
这种方法最简单直接,适合允许修改原酒店对象的场景:
1. 在组件中为每个酒店初始化状态
在获取到hotels数组后,给每个酒店对象添加一个isShow属性,默认设为false:
import { Component, OnInit } from '@angular/core'; @Component({ // 组件元数据(比如selector、templateUrl等) }) export class HotelsComponent implements OnInit { hotels: any[] = []; // 建议替换为你的酒店数据的具体类型 ngOnInit() { // 示例:从服务获取酒店数据后添加状态属性 // this.hotelService.getHotels().subscribe(hotels => { // this.hotels = hotels.map(hotel => ({ // ...hotel, // isShow: false // })); // }); // 模拟本地数据示例 this.hotels = [ { id: 1, name: '滨海度假酒店' }, { id: 2, name: '城市商务酒店' } ].map(hotel => ({ ...hotel, isShow: false })); } }
2. 修改模板绑定当前项的状态
把按钮的点击事件和*ngIf的判断都绑定到当前酒店对象的isShow属性上:
<div *ngFor="let hotel of hotels"> <div>Photo</div> <div>{{ hotel.name }}</div> <div> <button (click)="hotel.isShow = !hotel.isShow" type="button" class="btn btn-default btn"> <i class="glyphicon glyphicon-align-justify"></i> </button> </div> <div *ngIf="hotel.isShow">Additional information</div> </div>
这样每个酒店项都有自己独立的展开/收起状态,点击按钮只会切换当前项的显示。
方案二:单独维护状态映射对象(不修改原数据)
如果不想污染原酒店对象(比如数据来自后端且需要保持纯净),可以用一个独立的对象来记录每个酒店的展开状态:
1. 在组件中定义状态映射
import { Component, OnInit } from '@angular/core'; @Component({ // 组件元数据 }) export class HotelsComponent implements OnInit { hotels: any[] = []; showStates: { [key: number]: boolean } = {}; // 用酒店id作为键,存储展开状态 ngOnInit() { // 模拟本地数据示例 this.hotels = [ { id: 1, name: '滨海度假酒店' }, { id: 2, name: '城市商务酒店' } ]; // 初始化所有酒店的状态为false this.hotels.forEach(hotel => { this.showStates[hotel.id] = false; }); } // 切换展开状态的方法 toggleHotelInfo(hotelId: number) { this.showStates[hotelId] = !this.showStates[hotelId]; } }
2. 修改模板绑定状态映射
<div *ngFor="let hotel of hotels"> <div>Photo</div> <div>{{ hotel.name }}</div> <div> <button (click)="toggleHotelInfo(hotel.id)" type="button" class="btn btn-default btn"> <i class="glyphicon glyphicon-align-justify"></i> </button> </div> <div *ngIf="showStates[hotel.id]">Additional information</div> </div>
这种方式通过酒店的唯一标识(比如id)来关联状态,完全不会修改原酒店对象,更适合数据不可变的场景。
内容的提问来源于stack exchange,提问作者bsuart




