简体   繁体   中英

In Angular, what does *ngFor=“let item from list | async” mean?

This is used in this code example https://stackblitz.com/angular/jdamnnmgrae?file=app%2Fautocomplete-overview-example.ts .

The code snippet in question is:

<mat-option *ngFor="let state of filteredStates | async" [value]="state.name">

I've not yet seen this syntax so I'm puzzled as to what it does. When I remove the async call, the code no longer works so I need to understand it.

My belief is that this code is creating a list of Observables that is being sent to the async pipe but I haven't seen where this is documented in Angular's docs. If you know please respond.

import {map} from 'rxjs/operators/map';

export class AutocompleteOverviewExample {
// . . . other stuff omitted
  filteredStates: Observable<any[]>;

  constructor() {
    this.filteredStates = this.stateCtrl.valueChanges
    .pipe(
      startWith(''),
      map(state => state ? this.filterStates(state) : this.states.slice())
   );

So, the for loop likely looping over Observables because the Async pipe takes a Promise or Observable, and it's not a Promise. :-)

Useful links:

I haven't been able to find how pipe is used from FormControl.valueChanges, but hopefully this will become clear when this question is answered.

(Q) Can someone point me to some Angular documentation that explains what the "*ngFor | async" syntax means? or provide an explaination.

Searches for answer showed these results

The let state of filteredStates | async let state of filteredStates | async syntax can be thought of as this:

let state of (filteredStates | async)

The async pipe is applied to the filteredStates variable and not the whole for loop.

I think it should be obvious after looking at all of the other resources you looked at, but the async pipe is useful because it will subscribe to the observable for you (and additionally clean up the subscription so you don't need to worry about unsubscribing).

So, what is going on is that Angular is subscribing to your filteredStates observable. Each time a new list is streamed from your observable, the Angular *ngFor directive will loop over that list that was streamed.

Without the async pipe you would just have to subscribe to your filteredStates observable in your component and store the list as a property on your component (which you would then loop over in place of the filteredStates | async ). Note: There are a couple ways of how to handle the unsubscribing, this is just one way.

<mat-option *ngFor="let state of filteredStates" [value]="state.name">
class AutocompleteOverviewExample {
    filteredStates: State[] = [];
    subscription: Subscription = null;

    constructor() {
        this.subscription = this.stateCtrl.valueChanges
        .pipe(
            startWith(''),
            map(state => state ? this.filterStates(state) : this.states.slice())
        )
        .subscribe(states => this.filteredStates = states);
    }

    ngOnDestroy() {
        if (this.subscription) {
            this.subscription.unsubscribe();
            this.subscription = null;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM