Ionic 4 Correct way to show Loading, No records and data block

后端 未结 1 773
执念已碎
执念已碎 2021-01-29 04:04

Here\'s the problem. I have three states of almost all the pages in my app. 1. Loading (where I want to show spinner within the page and for that I have created a component alre

相关标签:
1条回答
  • 2021-01-29 04:27

    Advertisement: This is a response in Angular (I suppose can be inspiration for Ionic)

    You can create an operator, see this SO

    Well, change the operator to send 1 when start loading, -1 if finalize without no data and 0 if finalize with data:

    The operator:

    export const prepare = <T>(callback: () => void) => {
        return (source: Observable<T>): Observable<T> =>
            defer(() => {
                callback();
                return source;
            });
    };
    
    export const indicate = <T>(indicator: Subject<any>) => {
        let alive = true;
      let noData=false;
        return (source: Observable<T>): Observable<T> =>
            source.pipe(
                prepare(() =>
                    timer(500)
                        .pipe(
                            takeWhile(() => alive),
                            take(1)
                        )
                        .subscribe(() => {
                            indicator.next(1);
                        })
                ),
          tap(res=>{
            noData=(!res || (Array.isArray(res) && res.length<=0))
          }),
                finalize(() => {
                    alive = false;
                    indicator.next(noData?-1:0);
                })
            );
    };
    
    export const toClass = <T>(ClassType: { new(): T }) => (
        source: Observable<T>
    ) => source.pipe(map(val => Object.assign(new ClassType(), val)));
    

    the loading component:

    @Component({
      selector: 'app-loading',
      template:`
      <div *ngIf="dataService.loading$ | async as response">
        <div class="modal" (click)="dataService.loading$.next(0)">
            <div class="modal-content">
                <p *ngIf="response==1">Loading...</p>
                <p *ngIf="response==-1">Empty</p>
            </div>
        </div>
    </div>
      `,
      styleUrls: [ './loading.component.css' ]
    })
    export class LoadingComponent  {
      constructor(public dataService:DataService){}
    }
    

    See how close the modal using dataService.loading$.next(0) and how I declared as public my dataService in the constructor

    I make a simple example of use

    <button (click)="loadData()">load</button>
    <div>
        {{data}}
    </div>
    <app-loading></app-loading>
    

    And a simple service that simulate a call, return random null or the date time

    export class DataService {
      loading$ = new Subject<any>()
      getData():Observable<any>
      {
        const observable=of(Math.random()<.5?
                  'New Data at '+new Date():
                   null
        ).pipe(delay(1000))
    
        return observable.pipe(
          indicate(this.loading$))
      }
    }
    

    You can see the stackblitz, You see the "loading", then, some times you'll see that is empty, and another time the "loading" close.

    0 讨论(0)
提交回复
热议问题