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>
解决方案
问题出在几个核心点,逐一修正即可:
修正@ViewChild的类型声明
给input绑定ngbDatepicker指令后,对应的实例是NgbDatepicker而非NgbInputDatepicker,修改共享组件TS:@ViewChild('dp1', { static: false }) dateInputPicker: NgbDatepicker;加上
{ static: false }确保*ngIf渲染后能正确获取实例。移除调用组件的错误绑定
你在<app-date-picker>上额外添加了ngbDatepicker指令,这是冗余且错误的——共享组件内部已经有带该指令的input。外部的#dp1指向的是共享组件实例,不是内部的日期选择器,所以直接调用dp1.toggle()需要共享组件内部提供对应方法。优化共享组件的toggle方法
移除无用的event.dp1代码,用可选链避免空值报错:toggle() { this.dateInputPicker?.toggle(); }调用组件的按钮事件保持不变
因为#dp1指向共享组件实例,调用它的toggle方法即可触发内部日期选择器的显隐:<button class="btn btn-outline-secondary bi bi-calendar3" (click)="dp1.toggle()" type="button"></button>
调整完成后,点击按钮就能正常控制共享组件内日期选择器的弹窗显隐了。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

