Wie Todo's Antwort erwähnt, beginnt der Balken bei 0%. Sie müssen es auf 20% setzen und start()
anrufen. Allerdings wird start()
in einigen Intervallen nur schrittweise erhöht, und wenn es auf 100% trifft, verschwindet der Balken einfach und zeigt fälschlicherweise an, dass das Laden beendet ist. Es wäre nett, wenn start()
einen Callback akzeptiert, der bei jedem Schritt aufgerufen wird, so dass Sie ihn bei 90% stoppen können. Aber das tut es nicht.
So, hier ist das, was ich in unserem Projekt haben (Red Hat Automatische Migration Toolkit):
- In unserem HTTP-Service-Wrapper (Umgang mit OAuth), wir ein Ereignis ausgelöst,
- , die dann durch gefangen unsere
LoadingIndicatorService
.
LoadingIndicatorService
- hüllt den
SlimLoaderBarService
,
- und verfolgt, wie viele HTTP-Anforderungen dort im Gange sind.
- Dann zählt es den Prozentsatz und legt es auf eine Skala von 20 bis 90%.
- Wenn alle HTTP-Anfragen abgeschlossen sind, bleibt es für etwa eine Sekunde bei 90% und wird dann
complete()
aufgerufen.
Wenn Sie mehrere Anfragen nach jedem Navigationsschritt haben, sieht das ganz natürlich und bietet eine gute UX. Wenn Sie normalerweise nur eine Anfrage haben, können Sie entweder die CSS-basierte Animation anpassen (länger machen) oder start()
danach verwenden.
Hier sind einige der wichtigsten Codeteile:
@Injectable()
export class LoadingIndicatorService {
constructor(
private _slimBarService: SlimLoadingBarService,
private _eventBusService: EventBusService,
) {
// Register the LoadingSomething event listeners.
this._eventBusService.onEvent
.filter(event => event.isTypeOf(LoadingSomethingStartedEvent))
.subscribe((event: LoadingSomethingStartedEvent) => this.loadingStarted())
this._eventBusService.onEvent
.filter(event => event.isTypeOf(LoadingSomethingFinishedEvent))
.subscribe((event: LoadingSomethingFinishedEvent) => this.loadingFinished())
}
public getSlimService(){
return this._slimBarService;
}
private counter: number = 0;
private max: number = void 0;
private reset() {
this.counter = 0;
this.max = void 0;
}
public loadingStarted(){
this.counter++;
this.max = this.counter;
this.updateProgress();
}
public loadingFinished(){
this.counter--;
this.updateProgress();
}
private updateProgress() {
if (this.counter == 0) {
this._slimBarService.height = "2px";
this._slimBarService.visible = true;
this._slimBarService.progress = 95;
this.max = void 0;
Observable.timer(700).subscribe(() => {
this._slimBarService.complete();
});
}
else {
// max - counter = finished.
// If the things to load are added after something loaded, the progress would go back.
// But let's rely on that loading will start fast at the beginning.
// Start at 20, jump to 90.
let percent = 20 + 70 * (1 - (this.max - this.counter)/this.max);
this._slimBarService.height = "3px";
this._slimBarService.color = "#39a5dc";
this._slimBarService.visible = true;
this._slimBarService.progress = percent;
}
}
}
let responseObservable2 = responseObservable.do(
() => console.log("Request SUCCEEDED"),
() => console.log("Request FAILED"),
() => {
console.log("Request FINISHED");
if (this._eventBus) {
console.log("Request FINISHED, firing");
this._eventBus.fireEvent(new LoadingSomethingFinishedEvent(responseObservable))
}
}
);
HTTP-Service-Wrapper:
@Injectable()
export class WindupHttpService extends Http {
private configureRequest(method: RequestMethod, f: Function, url: string | Request, options: RequestOptionsArgs = {}, body?: any): Observable<Response> {
let responseObservable: Observable<Response> = ...
...
console.log("Load STARTED");
if (this._eventBus)
console.log("Load STARTED, firing");
this._eventBus.fireEvent(new LoadingSomethingStartedEvent(responseObservable));
return responseObservable2;
}
Für den kompletten Code, suchen github.com für Projekt Windup.