我尝试在
nx
工作区中的 Angular 18 项目中迁移到控制流格式。对于大多数模板来说,效果都很好,但对于一个 html,我收到以下错误:
[ngSwitch]: Error: Text node: "
◬" would result in invalid migrated @switch block structure. @switch can only have @case or @default as children.
我做了什么:
npx nx generate @angular/core:control-flow-migration
这是我的完整 html:
<ng-container *ngIf="!!type; else DeprecatedStructure">
<ng-container [ngSwitch]="type">
<ng-container *ngFor="let type of buttonTypes">
<button
*ngSwitchCase="type"
[style.display]="'flex'"
[style.flexDirection]="iconPosition === 'right' ? 'row' : 'row-reverse'"
[ngClass]="buttonClasses[type]"
[disabled]="disabled"
[type]="htmlType"
[id]="id"
[attr.data-test-id]="dataTestId"
(click)="handleClick($event)">
<ng-container [ngSwitch]="type">
<ng-container *ngSwitchDefault>
<span><ng-template [ngTemplateOutlet]="ButtonContentRef"></ng-template></span>
<mat-icon
*ngIf="!!icon"
class="fl-icon"
[ngClass]="{
right: iconPosition === 'right',
left: iconPosition === 'left'
}">
{{ icon }}
</mat-icon>
<mat-icon
*ngIf="!!svgIcon && !icon"
class="fl-icon"
[svgIcon]="svgIcon"
[ngClass]="{
right: iconPosition === 'right',
left: iconPosition === 'left'
}">
</mat-icon>
<span *ngIf="loading" class="loading loading-sm"></span>
</ng-container>
<ng-container *ngSwitchCase="icon">
<mat-icon class="fl-icon">{{ icon }}</mat-icon>
<span *ngIf="loading" class="loading loading-sm"></span>
</ng-container>
</ng-container>
</button>
</ng-container>
</ng-container>
</ng-container>
<ng-template #DeprecatedStructure>
<button
[class.btn]="!onlyIcon"
[class.btn-primary]="!onlyIcon && !textButton && !linkButton && !cardButton"
[class.btn-secondary]="secondary && !textButton && !linkButton && !cardButton"
[class.btn-destructive]="destructive && !textButton && !linkButton && !cardButton"
[class.btn-sm]="size === 'small'"
[class.btn-lg]="size === 'large'"
[class.btn-floating-primary]="onlyIcon"
[class.btn-floating-secondary]="onlyIcon && !!secondary"
[class.btn-floating-destructive]="onlyIcon && !!destructive"
[class.btn-flat-primary]="textButton"
[class.btn-flat-secondary]="textButton && secondary"
[class.btn-flat-destructive]="textButton && destructive"
[class.btn-plain-primary]="linkButton"
[class.btn-plain-secondary]="linkButton && secondary"
[class.btn-plain-destructive]="linkButton && destructive"
[class.btn-card]="cardButton"
[class.btn-loading]="loading"
[ngClass]="className"
[disabled]="!!disabled"
[type]="htmlType"
[id]="id"
[attr.data-test-id]="dataTestId"
(click)="handleClick($event)">
<mat-icon *ngIf="icon && iconPosition !== 'right'" class="fl-icon" [ngClass]="iconClassName">{{ icon }}</mat-icon>
<span *ngIf="!onlyIcon"><ng-template [ngTemplateOutlet]="ButtonContentRef"></ng-template></span>
<mat-icon *ngIf="icon && iconPosition === 'right'" class="fl-icon right" [ngClass]="iconClassName">{{
icon
}}</mat-icon>
<span *ngIf="loading" class="loading loading-sm"></span>
</button>
</ng-template>
<ng-template #ButtonContentRef>
<ng-content></ng-content>
</ng-template>
正如您在错误消息中看到的那样,
@switch
只能将 @case
或 @default
作为子级。但是,在您的情况下,迁移过程中会生成类似以下内容:
@switch(type) {
@for (...) {
@case () {}
}
}
上述声明无效。 Angular 无法自动修复此问题,这就是迁移失败的原因。要修复此问题,您可以将
*ngFor
移到 [ngSwitch]
之前:
<ng-container *ngFor="let type of buttonTypes">
<ng-container [ngSwitch]="type">
<button *ngSwitchCase="">
<!-- ... your other content -->
</ng-container>
</ng-container>
然后再次运行迁移。