Angular wing组件点击后所有encounter子列表展开,如何仅展示选中项?
解决方案
你不想将视图状态耦合到业务Wing类的思路是完全正确的,我们可以把展开状态完全存放在组件层,有两种常见实现方案:
方案1:单展开模式(同一时间仅允许展开一个wing)
这种方案适合不需要同时查看多个子列表的场景,仅用一个变量存储当前展开的wing标识即可:
首先修改wing.component.ts:
@Component({ selector: 'app-wing', templateUrl: './wing.component.html', styleUrls: ['./wing.component.css'] }) export class WingComponent implements OnInit { wings = WINGS; // 存储当前展开的wing名称,假设wing名称是唯一标识 selectedWingName?: string; constructor() { } ngOnInit(): void { } toggleEncounters(wingName: string) { // 如果点击的是当前已经展开的wing就收起,否则切换为点击的wing this.selectedWingName = this.selectedWingName === wingName ? undefined : wingName; } }
然后修改wing.component.html:
<ul> <li *ngFor="let wing of wings"> <button (click)="toggleEncounters(wing.getName())">{{ wing.getName() }}</button> <app-encounter *ngIf="selectedWingName === wing.getName()" [encounters]="wing.getEncounters()"> </app-encounter> </li> </ul>
方案2:多展开模式(允许多个wing同时展开)
如果需要同时查看多个子列表,可以用Set存储所有处于展开状态的wing标识:
修改wing.component.ts:
@Component({ selector: 'app-wing', templateUrl: './wing.component.html', styleUrls: ['./wing.component.css'] }) export class WingComponent implements OnInit { wings = WINGS; // 存储所有展开的wing名称 showEncountersSet = new Set<string>(); constructor() { } ngOnInit(): void { } toggleEncounters(wingName: string) { if (this.showEncountersSet.has(wingName)) { this.showEncountersSet.delete(wingName); } else { this.showEncountersSet.add(wingName); } } }
修改wing.component.html:
<ul> <li *ngFor="let wing of wings"> <button (click)="toggleEncounters(wing.getName())">{{ wing.getName() }}</button> <app-encounter *ngIf="showEncountersSet.has(wing.getName())" [encounters]="wing.getEncounters()"> </app-encounter> </li> </ul>
说明
两种方案都没有修改业务类Wing的定义,所有视图状态都存放在组件内部,完全解耦了业务逻辑和视图展示逻辑。如果你的wing存在重名的可能,也可以给Wing类加个只读的id字段作为唯一标识,替换掉示例中用name做标识的逻辑即可。
内容的提问来源于stack exchange,提问作者Jack_Russell
相关产品推荐
相关产品推荐

