Angular Bootstrap动态生成Dropdown:TypeScript替代#引用方案问询
动态生成NgbDropdown后在TypeScript中访问实例的方法
当用@for循环批量生成NgbDropdown时,不需要给每个组件单独定义模板引用变量,以下两种方法可以帮你在TypeScript中获取并操作这些动态实例:
方法一:使用@ViewChildren批量获取所有实例
通过@ViewChildren(NgbDropdown)可以获取页面上所有NgbDropdown的实例集合,之后就能遍历或按索引操作特定的Dropdown。
组件TypeScript代码
import { Component, ViewChildren, QueryList, AfterViewInit } from '@angular/core'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-dropdowns', templateUrl: './dropdowns.component.html' }) export class DropdownsComponent implements AfterViewInit { // 模拟从数据库获取的数据源 dropdownData = [ { id: 1, label: 'Dropdown 1', items: ['Action 1-1', 'Action 1-2'] }, { id: 2, label: 'Dropdown 2', items: ['Action 2-1', 'Action 2-2'] } ]; // 获取所有NgbDropdown实例 @ViewChildren(NgbDropdown) dropdowns!: QueryList<NgbDropdown>; ngAfterViewInit() { // 组件初始化完成后可以访问实例集合 console.log('所有Dropdown实例:', this.dropdowns); } // 示例:打开指定索引的Dropdown openDropdownByIndex(index: number) { const dropdown = this.dropdowns.toArray()[index]; if (dropdown) { dropdown.open(); } } }
模板代码
@for (item of dropdownData; track item.id; let i = $index) { <div class="d-inline-block" ngbDropdown> <button type="button" class="btn btn-outline-primary me-2" [id]="'dropdown-' + item.id" ngbDropdownAnchor (click)="openDropdownByIndex(i)" > {{ item.label }} </button> <div ngbDropdownMenu [aria-labelledby]="'dropdown-' + item.id"> @for (action of item.items; track action) { <button ngbDropdownItem>{{ action }}</button> } </div> </div> }
方法二:通过初始化事件绑定单个实例到数组
利用NgbDropdown的ngbDropdownInit事件,把每个动态生成的实例存入组件内的数组,这样可以直接和数据源的项一一对应,操作更精准。
组件TypeScript代码
import { Component } from '@angular/core'; import { NgbDropdown } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'app-dropdowns', templateUrl: './dropdowns.component.html' }) export class DropdownsComponent { dropdownData = [ { id: 1, label: 'Dropdown 1', items: ['Action 1-1', 'Action 1-2'] }, { id: 2, label: 'Dropdown 2', items: ['Action 2-1', 'Action 2-2'] } ]; // 存储每个Dropdown的实例 dropdownInstances: NgbDropdown[] = []; // 当Dropdown初始化时,将实例存入数组 onDropdownInit(dropdown: NgbDropdown) { this.dropdownInstances.push(dropdown); } // 示例:根据数据源ID打开对应的Dropdown openDropdownById(id: number) { const targetIndex = this.dropdownData.findIndex(item => item.id === id); if (targetIndex !== -1) { this.dropdownInstances[targetIndex].open(); } } }
模板代码
@for (item of dropdownData; track item.id) { <div class="d-inline-block" ngbDropdown (ngbDropdownInit)="onDropdownInit($event)"> <button type="button" class="btn btn-outline-primary me-2" [id]="'dropdown-' + item.id" ngbDropdownAnchor (click)="openDropdownById(item.id)" > {{ item.label }} </button> <div ngbDropdownMenu [aria-labelledby]="'dropdown-' + item.id"> @for (action of item.items; track action) { <button ngbDropdownItem>{{ action }}</button> } </div> </div> }
两种方法都能实现需求,第一种适合批量操作所有Dropdown,第二种更适合精准定位单个实例,你可以根据实际场景选择。
内容的提问来源于stack exchange,提问作者parascus
相关产品推荐
相关产品推荐

