You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:36:05