feat(fp): WP-06 — kill $any() in templates (18x)
Make AsyncLoadedDirective generic with a static ngTemplateContextGuard for AsyncComponent's own internal typing. That can't propagate to consumer `<ng-template appAsyncLoaded let-p>` sites though -- Angular only infers a structural directive's type parameter from an input bound on that same node, not from a sibling input on the parent component -- so the ~9 root-cause consumers (dashboard, registration-detail, aanvraag-detail, registratie-wizard) instead unwrap the RemoteData Success value via a typed computed() and narrow it locally with `@if (x(); as p)`. The remaining union-narrowing casts (registration-summary, showcase concepts page) are replaced with a stable @let binding and a direct resource read, respectively. Documented as a deviation in WP-06's backlog file.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { Component, computed, inject } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';
|
||||
import { SkeletonComponent } from '@shared/ui/skeleton/skeleton.component';
|
||||
@@ -30,24 +30,26 @@ import { detailRows } from '@registratie/domain/aanvraag-view';
|
||||
backLink="/dashboard"
|
||||
>
|
||||
<app-async [data]="store.applications()">
|
||||
<ng-template appAsyncLoaded let-list>
|
||||
@let a = find($any(list));
|
||||
@if (a) {
|
||||
<app-data-block
|
||||
i18n-ariaLabel="@@aanvraagDetail.ariaLabel"
|
||||
ariaLabel="Aanvraaggegevens"
|
||||
>
|
||||
@for (row of rows(a); track row.key) {
|
||||
<div app-data-row [key]="row.key" [value]="row.value"></div>
|
||||
}
|
||||
</app-data-block>
|
||||
<app-alert class="app-section" type="info" i18n="@@aanvraagDetail.stub">
|
||||
De volledige afhandeling van deze aanvraag is nog niet beschikbaar in deze POC.
|
||||
</app-alert>
|
||||
} @else {
|
||||
<app-alert type="warning" i18n="@@aanvraagDetail.nietGevonden"
|
||||
>Deze aanvraag is niet gevonden.</app-alert
|
||||
>
|
||||
<ng-template appAsyncLoaded>
|
||||
@if (applications(); as list) {
|
||||
@let a = find(list);
|
||||
@if (a) {
|
||||
<app-data-block
|
||||
i18n-ariaLabel="@@aanvraagDetail.ariaLabel"
|
||||
ariaLabel="Aanvraaggegevens"
|
||||
>
|
||||
@for (row of rows(a); track row.key) {
|
||||
<div app-data-row [key]="row.key" [value]="row.value"></div>
|
||||
}
|
||||
</app-data-block>
|
||||
<app-alert class="app-section" type="info" i18n="@@aanvraagDetail.stub">
|
||||
De volledige afhandeling van deze aanvraag is nog niet beschikbaar in deze POC.
|
||||
</app-alert>
|
||||
} @else {
|
||||
<app-alert type="warning" i18n="@@aanvraagDetail.nietGevonden"
|
||||
>Deze aanvraag is niet gevonden.</app-alert
|
||||
>
|
||||
}
|
||||
}
|
||||
</ng-template>
|
||||
<ng-template appAsyncLoading>
|
||||
@@ -63,4 +65,10 @@ export class AanvraagDetailPage {
|
||||
|
||||
protected find = (list: Aanvraag[]): Aanvraag | undefined => list.find((a) => a.id === this.id);
|
||||
protected rows = detailRows;
|
||||
|
||||
/** See DashboardPage's `profile` for why this narrows via a computed instead of `let-`. */
|
||||
protected readonly applications = computed(() => {
|
||||
const rd = this.store.applications();
|
||||
return rd.tag === 'Success' ? rd.value : undefined;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user