I wrote this code in HTML, which is very very long. I used ngSwitch for 3 cases and in the default case I have 4 different small cases. All of these cases used the same structure of icon. How could I make my HTML shorter? How could I remove the business logic from HTML?
The rule to show different icons is:
Serviceflag (boolean) > warnflag (boolean) > serviceflag (boolean) > timekey(number)
For Example: If the code includes all of them then the icon of Serviceflag should be shown. If the code includes warnflag and timekey then the icon of warnflag should be shown.
<ng-template #defaultModalHeaderTemplate>
<app-device-status-information
*ngIf="status"
[statusInformation]="status"
></app-device-status-information>
<app-device-status-information
*ngIf="information"
[statusInformation]="information"
></app-device-status-information>
</ng-template>
<div
[ngSwitch]="
!(status.warnFlag && !status.serviceFlag && !status.errorFlag) ||
!(status.errorFlag && !status.serviceFlag)
"
>
<div
style="background-color: rgba(241, 90, 34, 0.1)"
*ngSwitchCase="status.warnFlag && !status.serviceFlag && !status.errorFlag"
>
<div style="padding: 36px 0px 24px 24px">
<div >
<ng-container>
<i
c8yicon="warning"
style="font-size: 80px"
ng-reflect-c8y-icon="warning"
></i>
</ng-container>
</div>
<div >
<ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
</div>
</div>
</div>
<div
*ngSwitchCase="status.errorFlag && !status.serviceFlag"
style="background-color: rgba(217, 30, 24, 0.1)"
>
<div style="padding: 36px 0px 24px 24px">
<div >
<ng-container style="background-color: bg-dark-warning">
<i
c8yicon="exclamation-circle"
style="font-size: 80px"
ng-reflect-c8y-icon="exclamation-circle"
></i>
</ng-container>
</div>
<div >
<ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
</div>
</div>
</div>
<div *ngSwitchDefault>
<div >
<div style="padding-left: 48px">
<ng-container *ngIf="status.serviceFlag">
<i
c8yicon="wrench"
style="font-size: 80px"
ng-reflect-c8y-icon="wrench"
></i>
</ng-container>
<ng-container
*ngIf="
information.timeKey === 1 &&
!status.warnFlag &&
!status.serviceFlag &&
!status.errorFlag
"
>
<i
c8yicon="check-circle"
style="font-size: 80px"
ng-reflect-c8y-icon="check-circle"
></i>
</ng-container>
<ng-container
*ngIf="
(information.timeKey === 2 ||
information.timeKey === 3 ||
information.timeKey === 4 ||
information.timeKey === 6) &&
!status.warnFlag &&
!status.serviceFlag &&
!status.errorFlag
"
>
<i
c8yicon="stop-circle"
style="font-size: 80px"
ng-reflect-c8y-icon="stop-circle"
></i>
</ng-container>
<ng-container
*ngIf="
information.timeKey === 5 &&
!status.warnFlag &&
!status.serviceFlag &&
!status.errorFlag
"
>
<i
c8yicon="exclamation-circle"
style="font-size: 80px"
ng-reflect-c8y-icon="exclamation-circle"
></i>
</ng-container>
</div>
<div >
<ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
</div>
</div>
</div>
</div>
CodePudding user response:
If you convert all of the values to Observable
you can use a combine latest from rxjs
to create a shouldShow flag that you can use in the html
shouldShowContent$ = combineLatest([this.information, this.warnFlag, this.serviceFlag, this.errorFlag,])
.pipe(map(x => x.every(c => c == false)))
Usage:
<div *ngIf="shouldShowContent$ | async">
Content
</div>
And the rest can be applied in a similar pattern
CodePudding user response:
Start by declaring getters in your typescript, while also reducing and factoring your logic
get flagType(): 0 | 1 | 2 {
// Adapt your logic here
return this.status.errorFlag ? 0 :
this.status.warnFlag ? 1 :
this.status.serviceFlag ? 2 : null;
}
get bgColor(): string {
// Again, adapt your colors here depending on the above
return ['red', 'yellow', 'green'][this.flagType];
}
get icon() {
// Again, adapt
return ['error', 'warning', 'service'][this.flagType];
}
// Add every getter you need
Then, in your HTML, you can call it once, with the getters.
<div
[style.background-color]="bgColor"
>
<div style="padding: 36px 0px 24px 24px">
<div >
<ng-container>
<i
[c8yicon]="icon"
style="font-size: 80px"
></i>
</ng-container>
</div>
<div >
<ng-container *ngTemplateOutlet="defaultModalHeaderTemplate"></ng-container>
</div>
</div>
</div>