2017-01-12 1 views
4

Ich habe einen wirklich einfachen Testfall, wo ich eine große Liste von Json-Einträgen sage sagen 2000 Elemente. Ich möchte einfach alle diese Elemente auf einer Seite anzeigen. (Vergessen Sie, ob das ein gutes Design ist oder nicht).Aurelia for.repeat warten Spinner

Ich habe einen Standard-Spinner in meiner index.html angegeben, der beim Laden der Seite und beim Wechseln der Seiten angezeigt wird. Der Drehknopf bleibt jedoch stehen und die Seite wird angezeigt, bevor die For.repeat-Schleife abgeschlossen ist.

Was ist der beste Weg, damit umzugehen. Ich habe versucht, einen neuen Spinner diese Seite nur für das for.repeat hinzuzufügen, aber es scheint keine Möglichkeit zu geben, zu wissen, wann die Schleife abgeschlossen ist. Ich habe versucht, TaskQueue ohne Erfolg zu verwenden. Ich könnte ein SetTimeout als schmutzigen Hack verwenden, aber ich würde gerne wissen, wie man mit dieser Art von Dingen richtig umgehen kann.

Dank

+0

Ich vermute, Sie könnten die 'isBound' -Eigenschaft verwenden, die hier beschrieben wird: http://aurelia.io/hub.html#/doc/api/aurelia/binding/latest/interface/Binding. Oder setzen Sie eine Variable in Ihrem Konstruktor ('bindSpinner = 1;') und löschen Sie sie dann in Ihrer 'attached() 'lifecycle Methode (' bindSpinner = 0; '). – LStarky

Antwort

1

Ich bin mir ziemlich sicher, dass dies funktionieren würde:

export class LongDataList { 

    constructor() { 
    // start the spinner 
    this.bindingSpinner = 1; 
    } 

    attached() { 
    // stop the spinner 
    this.bindingSpinner = 0; 
    } 

} 

Und in der Vorlage, so etwas wie diese:

<template> 

    <!-- spinner --> 
    <span if.bind="bindingSpinner"> 
    <i class="fa fa-spinner fa-spin fa-lg"></i> 
    </span> 

    <!-- List of records --> 
    <table> 
    <thead> 
     <tr> 
     <th>Username</th> 
     <th>Password</th> 
     <th>First name</th> 
     <th>Last name</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr repeat.for="record of records"> 
     <td>${record.user_username}</td> 
     <td>${record.user_password}</td> 
     <td>${record.p_fname}</td> 
     <td>${record.p_lname}</td> 
     </tr> 
    </tbody> 
    </table> 

</template> 

Schließlich, wenn Sie die Spinner angezeigt werden sollen In einem anderen Modul könnten Sie die Eigenschaft entweder von der übergeordneten Komponente binden:

<long-data-list binding-spinner.bind="parent-binding-spinner"></long-data-list> 

Oder Sie könnten Aurelia eventAggregator verwenden, um die Ereignisse zu kommunizieren, um den Spinner zu starten und zu stoppen. Der erste ist jedoch einfacher.

+0

Ich habe diesen Ansatz vorher versucht. Die angehängte Methode wird aufgerufen, bevor die Liste gerendert wird. Das Ergebnis ist, dass der Spinner im Grunde nicht angezeigt wird, da er fast sofort gestoppt wird. –

+0

Ok. Dies als richtig markieren (Du warst zuerst). Wirklich alle Antworten waren korrekt. Mein Problem war ich hatte einen Anruf, um dies abzuwarten. GetData(); in der activate() -Methode und ich habe dann versucht, den Spinner in attached() zu stoppen. Ich musste die Daten auch anhängen. –

1

Ich habe einen Gist für Sie basierend auf der Antwort von @LStarky erstellt, die zeigt, wie der Spinner funktioniert.

Ich schätze dein Problem ist, deine Daten sind direkt verfügbar und daher verschwindet der Spinner sofort. In meinem Beispiel werden Daten von einem entfernten Standort geladen. Während dieser Zeit wird der Spinner gezeigt:

https://gist.run/?id=75d5ba1e321a918ee16366f7c2c4d0f2

Dies ist ein wichtiger Punkt:

export class App { 
    bindingSpinner = 1; 
    data = []; 

    attached() { 
    this.bindingSpinner = 1; 
    fetch('https://jsonplaceholder.typicode.com/photos').then(response => { 
     // stop the spinner 
     return response.json() 
    }).then(data => { 
     this.data = data; 
     this.bindingSpinner = 0; 
    }); 
    } 
} 
1

Sie haben den activate() Lebenszyklus Haken zu verwenden. Wenn Sie ein Versprechen in activate() zurückgeben, wird die Seite nur angezeigt, wenn der Vorgang abgeschlossen ist. Zum Beispiel:

activate() { 
    return new Promise((res, rej) => { 
    this.items = 50000; 
    res(); 
    }); 
} 

Selbst Erklärt Lauf Beispiel https://gist.run/?id=eb239baf7255bfe1c613be1dbbe44939

1

Es klingt wie Ihr Problem, dass die sein könnte Rendering der Listenelemente zu lange dauert. Wenn Sie mit wirklich langen Listen wie dieser arbeiten, können Sie von der Virtualisierung profitieren, indem Sie das aurelia-ui-virtualization Paket verwenden.

Installieren Sie das Paket über JSPM

jspm install aurelia-ui-virtualization 

laden Sie das Paket:

aurelia.use 
    .standardConfiguration() 
    .plugin('aurelia-ui-virtualization'); 

und einfach ersetzen Ihre repeat.for mit virtual-repeat.for verbindlich. Das tatsächliche Rendern der Seite sollte nun unmittelbar erfolgen, verglichen mit dem Versuch, über eine große Liste von Elementen zu iterieren.