Angular 6迁移至12后*ngIf;Then;Else模板引用报错求助
Angular 6→12迁移:ngIfElse模板引用冲突问题修复
错误原因
报错的核心是模板引用变量重名:你给input元素定义了#selectAll,同时又给ng-template定义了同名的#selectAll。Angular 12的模板检查机制更严格,会将else selectAll中的selectAll解析为input元素(ElementRef类型),但ngIfElse要求传入的是TemplateRef类型,因此触发类型不匹配错误。
重构方案
方案1:重命名input的模板引用变量(推荐)
通过修改input的模板变量名,彻底区分元素和模板的引用,同时同步更新TS中的@ViewChild绑定:
修改后的模板代码
<table> <thead></thead> <tr> <th> <input #selectAllCheckbox type="checkbox" [checked]="myFunctionName()" (click)="toggleSelection()" /> </th> <th> <ng-container *ngIf="myFunctionName(); then removeAll ; else selectAll"></ng-container> <ng-template #selectAll>{{SELECT_ALL}}</ng-template> <ng-template #removeAll>{{DESELECT_ALL}}</ng-template> </th> </tr> </table>
修改后的TS代码
@ViewChild('selectAllCheckbox' , {static: true}) selectAllCheckbox!: ElementRef<HTMLInputElement>; myFunctionName(): boolean { if (this.checkboxes) { // 原有业务逻辑 } return false; }
方案2:重命名ng-template的模板引用变量
如果不想修改TS代码,可以仅调整ng-template的变量名,避免和input冲突:
修改后的模板代码
<table> <thead></thead> <tr> <th> <input #selectAll type="checkbox" [checked]="myFunctionName()" (click)="toggleSelection()" /> </th> <th> <ng-container *ngIf="myFunctionName(); then removeAll ; else selectAllText"></ng-container> <ng-template #selectAllText>{{SELECT_ALL}}</ng-template> <ng-template #removeAll>{{DESELECT_ALL}}</ng-template> </th> </tr> </table>
额外性能优化
模板中多次调用myFunctionName()会在Angular变更检测时重复执行,建议将方法转换为getter属性,减少不必要的计算:
// TS中替换原有方法为属性 get isAllSelected(): boolean { if (this.checkboxes) { // 原有myFunctionName的业务逻辑 } return false; }
模板中同步替换为属性调用:
<input #selectAllCheckbox type="checkbox" [checked]="isAllSelected" (click)="toggleSelection()" /> <ng-container *ngIf="isAllSelected; then removeAll ; else selectAll"></ng-container>
内容的提问来源于stack exchange,提问作者Flavio
相关产品推荐
相关产品推荐

