angular - Hur binder jag resultatet av en @for till en variabel?


I Angular 16 (och tidigare) var det möjligt att använda "as" bakom en for-loop för att deklarera de filtrerade resultaten som en variabel.

Så här:

<div *ngFor="let item of (items | pipe: Query) as results">
{{item}}
</div>

Hur skulle jag uppnå detta i Angular 17?

Jag har redan försökt använda

@for (let item of (items | pipe: Query) as results; track item.id) {
<div>
{{item}}
</div>
}

men det fungerar inte. Jag skulle vilja kunna använda mina filtrerade resultat och lagra dem i en items-array.

Är det möjligt? All hjälp skulle uppskattas mycket!

Svar #1

Kollektionsaliasering (d.v.s. med as-nyckelordet) stöds inte med @for i Angular 17s styrflödessyntax.

Se detta problem på GitHub, med det relevanta citatet här:

@for stöder som nämnts inte aliasering av samlingen.

Den angulära migreringen loggar för närvarande inte, men borde, en varning när as upptäcks under migreringen. Det finns en öppen fråga för att åtgärda det.

Som ett alternativ, om du vill ha ett uttryckligt alias, är att extrahera resultaten med pipen i en @if, och sedan använda dem i @for. Något sådant här:

@if (items$ | async; as results) {

@for (item of results; track item.id) {
<div>
{{item}}
</div>
}

Svar #2

Tänk att med @for-syntaxen kan du inte deklarera den lokala variabeln med as.

Du kan titta på att arbeta med NgTemplateOutlet.

<ng-container
  [ngTemplateOutlet]="resultTemplate"
  [ngTemplateOutletContext]="{$implicit: items | pipe: Query}"
>
</ng-container>

<ng-template #resultTemplate let-results>
  {{ results | json }} 
  @for (item of results; track item.id) {
    <div>{{item | json}}</div>
  }
</ng-template>

Alternativt kan du använda Pipe i komponenten.

@Component({
  selector: 'app-root',
  standalone: true,
  templateUrl: `main.html`,
  providers: [YourQueryPipe]
})
export class App {
  name = 'Angular';

  items = [{ id: '1' }, { id: '2' }, { id: '3' }];

  constructor(private queryPipe: YourQueryPipe) {}

  queryItems = this.queryPipe.transform(this.items, /* value/fiter needed in YourQueryPipe */)
}
@for (item of queryItems; track item.id) {
  <div>{{item}}</div>
}

Demo @ StackBlitz