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

NgbDatepicker共享组件弹窗toggle()非函数报错与调用失效问题

问题:封装的NgbDatepicker共享组件toggle功能失效

我封装了一款弹窗式NgbDatepicker共享组件,在其他组件中调用时,弹窗的打开/关闭(toggle)功能失效。试过用NgbDatepicker和NgbInputDatepicker两种方式,问题都没解决,需求是点击按钮控制弹窗显隐。直接用ng-bootstrap官网的「弹窗范围选择」示例能正常运行,但通过共享组件调用就出问题。

报错信息

ERROR TypeError: this.dateInputPicker.toggle is not a function
    at DatePickerComponent.toggle (date-picker.component.ts:58:24)

代码片段

共享组件HTML

<div class="icon-small" *ngIf="!simpleDatePicker">
    <form class="row row-cols-sm-auto">
        <div class="col-12">
            <div class="dp-hidden position-absolute">
                <div class="input-group">
                    <input
                        id="dp1"
                        name="datepicker"
                        class="form-control"
                        ngbDatepicker
                        #dp1
                        [autoClose]="'outside'"
                        (dateSelect)="onDateSelection($event)"
                        [displayMonths]="2"
                        outsideDays="hidden"
                        [startDate]="fromDate!"
                    />
                </div>
            </div>
        </div>
    </form>
</div>

共享组件TS

@Component({
  selector: 'app-date-picker',
  templateUrl: './date-picker.component.html',
  styleUrls: ['./date-picker.component.css']
})

export class DatePickerComponent implements OnInit {

...
@ViewChild('dp1') dateInputPicker: NgbInputDatepicker;
...
...
toggle(event) {
  console.log(event.dp1); // 输出undefined
  this.dateInputPicker.toggle(); // 报错:this.dateInputPicker.toggle is not a function
  
}

调用组件HTML

<form class="row row-cols-sm-auto">
    <div class="col-12">
        <div class="dp-hidden position-absolute">
            <div class="input-group">
                <app-date-picker
                    name="datepicker"
                    class="form-control"
                    ngbDatepicker
                    #dp1
                    [simpleDatePicker]="false"
                    [autoClose]="'outside'"
                    (dateSelect)="onDateSelection($event)"
                    [displayMonths]="2"
                    [dayTemplate]="t"
                    outsideDays="hidden"
                    [weekdays]="false"
                    [startDate]="fromDate!"
                    tabindex="-1"></app-date-picker>
                <ng-template #t let-date let-focused="focused">
                    <span
                        class="custom-day"
                        [class.focused]="focused"
                        [class.range]="isRange(date)"
                        [class.faded]="isHovered(date) || isInside(date)"
                        (mouseenter)="hoveredDate = date"
                        (mouseleave)="hoveredDate = null"
                    >
                        {{ date.day }}
                    </span>
                </ng-template>
            </div>
        </div>
        <div class="input-group">
            <input
                #dpFromDate
                class="form-control"
                placeholder="yyyy-mm-dd"
                name="dpFromDate"
                [value]="formatter.format(fromDate)"
                (input)="fromDate = validateInput(fromDate, dpFromDate.value)"
            />
            <button class="btn btn-outline-secondary bi bi-calendar3" (click)="dp1.toggle($event)" type="button"></button>
        </div>
    </div>
</form>

解决方案

问题出在几个核心点,逐一修正即可:

  1. 修正@ViewChild的类型声明
    给input绑定ngbDatepicker指令后,对应的实例是NgbDatepicker而非NgbInputDatepicker,修改共享组件TS:

    @ViewChild('dp1', { static: false }) dateInputPicker: NgbDatepicker;
    

    加上{ static: false }确保*ngIf渲染后能正确获取实例。

  2. 移除调用组件的错误绑定
    你在<app-date-picker>上额外添加了ngbDatepicker指令,这是冗余且错误的——共享组件内部已经有带该指令的input。外部的#dp1指向的是共享组件实例,不是内部的日期选择器,所以直接调用dp1.toggle()需要共享组件内部提供对应方法。

  3. 优化共享组件的toggle方法
    移除无用的event.dp1代码,用可选链避免空值报错:

    toggle() {
      this.dateInputPicker?.toggle();
    }
    
  4. 调用组件的按钮事件保持不变
    因为#dp1指向共享组件实例,调用它的toggle方法即可触发内部日期选择器的显隐:

    <button class="btn btn-outline-secondary bi bi-calendar3" (click)="dp1.toggle()" type="button"></button>
    

调整完成后,点击按钮就能正常控制共享组件内日期选择器的弹窗显隐了。


内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:45:32