Angular Material 15:mat-icon-button包裹input标签无法点击的修复方法
Angular Material 15对mat-icon-button的内部事件处理逻辑做了调整,它会拦截按钮内部元素的点击事件,导致嵌套的<input type="file">无法被触发——这就是为什么换成mat-raised-button能正常工作的原因。以下是几种可行的修复方案:
方案一:手动触发文件输入框的点击事件
将文件输入框隐藏,通过按钮的click事件主动触发输入框的点击行为:
<li> <button [attr.station-action]="'upload-file'" color="primary" mat-icon-button [disabled]="!estimateStation.canUpload" (click)="document.getElementById('upload-input-' + stationIndex)?.click()"> <input style="display: none;" [disabled]="!estimateStation.canUpload" title="" id="upload-input-{{stationIndex}}" type="file" (change)="onFileSelected($event, estimateStation, estimate)"> <span class="icon-upload"></span> </button> </li>
如果要遵循Angular最佳实践,推荐用ViewChild获取输入框引用:
组件类中添加:
@ViewChild('uploadInput') uploadInput!: ElementRef<HTMLInputElement>;
模板修改为:
<li> <button [attr.station-action]="'upload-file'" color="primary" mat-icon-button [disabled]="!estimateStation.canUpload" (click)="uploadInput.nativeElement.click()"> <input #uploadInput style="display: none;" [disabled]="!estimateStation.canUpload" title="" type="file" (change)="onFileSelected($event, estimateStation, estimate)"> <span class="icon-upload"></span> </button> </li>
方案二:通过CSS让输入框覆盖按钮区域
用CSS将文件输入框设置为透明并铺满整个按钮,点击按钮时实际触发的是输入框:
<li> <button [attr.station-action]="'upload-file'" color="primary" mat-icon-button [disabled]="!estimateStation.canUpload" style="position: relative; overflow: hidden;"> <input [disabled]="!estimateStation.canUpload" title="" id="upload-input-{{stationIndex}}" type="file" (change)="onFileSelected($event, estimateStation, estimate)" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer;"> <span class="icon-upload"></span> </button> </li>
方案三:替换为MatButtonToggle(可选)
如果上述方案不适用,可以用mat-button-toggle替代mat-icon-button,它的事件处理逻辑不会拦截内部输入框的点击:
<li> <mat-button-toggle [attr.station-action]="'upload-file'" color="primary" [disabled]="!estimateStation.canUpload"> <input [disabled]="!estimateStation.canUpload" title="" id="upload-input-{{stationIndex}}" type="file" (change)="onFileSelected($event, estimateStation, estimate)"> <span class="icon-upload"></span> </mat-button-toggle> </li>
内容的提问来源于stack exchange,提问作者Serhii Vakulchyk
相关产品推荐
相关产品推荐

