html - Cum să afișezi un indicator de încărcare până când toate apelurile HTTP asincrone sunt finalizate - Angular


Întrebarea mea este cum să afișez un indicator de încărcare până când toate solicitările mele HTTP asincrone sunt finalizate. În acest fel, nu aș afișa părți din ecran până când toate datele nu sunt primite de la server.

Cea mai mare problemă a mea este că am componente care sunt declanșate în mod specific prin HTML, așa că nu pot pur și simplu să pun o declarație *ngIf peste o parte din HTML atunci când vreau să o afișez.

Iată ce am până acum. Pentru informarea ta, variabila Template care declanșează în prezent vizibilitatea HTML-ului este setată atunci când una dintre cererile HTTP se finalizează în acest component. Vreau să aștept ca cererile HTTP ale componentului copil să se finalizeze înainte de a afișa HTML-ul, dar trebuie să execut logica în HTML pentru a putea apela componentele copil.

Instrucțiunea *ngIf NU funcționează în prezent în modul în care doresc, arăt doar ce fac în prezent.

<div class="col-sm-12"
            *ngIf="Template">
    <div id="nav" style="height: 200px">
        <div id="outer"
             style="width: 100%">
            <div id="inner">
                <o-grid>
                </o-grid>
            </div>
        </div>
    </div>
    <collapsible-panel *ngFor="let s of Template?.s; let i = index"
                       [title]="s.header">
        <div *ngFor="let c of s.c">
            <fact [eC]="c.c"
                    [label]="c.l">
            </fact>
        </div>
    </collapsible-panel>

    <collapsible-panel title="T">
        <div>
            <i-f >
            </i-f>
        </div>
    </collapsible-panel>
</div>
<div *ngIf="!Template" class="spinner"></div>

EDITARE (SOLUȚIE): Iată soluția pe care am implementat-o, conform răspunsului de mai jos de la @danday74.

Am instanțiat variabila în interiorul serviciului meu unde fac toate cererile http. Am definit-o ca fiind adevărată la început și am setat-o pe fals într-unul dintre componentele copil când subscribe se finalizează.

Voi trebui doar să mă asigur în viitor să setez cService.asyncRequestsInProgress pe fals oriunde are loc ultima cerere HTTP asincronă, dacă se schimbă vreodată.

HTML părinte:

<div class="col-sm-12"
             [ngClass]="{hideMe:cService.asyncRequestsInProgress}">
    ......
</div>
<div *ngIf="cService.asyncRequestsInProgress" class="spinner"></div>

Serviciu :

@Injectable()
export class CService {

    asyncRequestsInProgress: boolean = true;
    constructor(public http: HttpClient) { }
}

Componenta copil (Unde se finalizează ultima cerere asincronă):

export class FComponent implements OnInit {
    ....
    doSomething() {
        this.cService.getWhatever().subscribe(x => {
            this.cService.asyncRequestsInProgress = false;
        }
    }
}

styles.css

.hideMe {
  visibility: hidden;
}

Răspuns #1

Ai putea folosi un resolver. Un resolver asigură încărcarea datelor înainte ca componenta să se încarce.

Alternativ, dacă nu vrei să folosești *ngIf, ai putea doar să folosești [ngClass]="{hideMe: allAsyncRequestsComplete}" pentru a stiliza partea pe care nu vrei să o afișezi până când încărcarea este completă. CSS-ul ar putea fi:

.hideMe {
  visibility: hidden;
}

Și setează allAsyncRequestsComplete la true când încărcarea este terminată.

Răspunsul #2

Poți folosi rezolvatoare pentru încărcare, apoi în app.component.ts, setează variabila ta la adevărat sau fals în funcție de eveniment:

navigationInterceptor(event: RouterEvent): void {
  if (event instanceof NavigationStart) {
    //true
  }
  if (event instanceof NavigationEnd) {
    //false
  }

  // Set loading state to false in both of the below events to hide the spinner in case a request fails
  if (event instanceof NavigationCancel) {
    //false
  }
  if (event instanceof NavigationError) {
    //false
  }
}