如何在加载异步列表时在Angular2中使用CSS微调器?

时间:2016-12-02 03:56:27

标签: css angular spinner

这看起来很简单,但我找不到任何解决方法。 我尝试做的是在加载异步列表时使用CSS微调器/加载器。我尝试了各种各样的事情,包括尝试使用ngSwitch,但到目前为止没有任何作用,旋转器只是无限旋转。这是基本代码:

<div class="col-md-2 mediaContainer">
  Media:
  <ul class="media">
    <li *ngFor="let medium of media | async"
        [class.selected] = "medium === selectedMedium"
        (click)="onSelect(medium)">
      {{medium.name}}
    </li>
  </ul>
</div>

虽然我尝试了很多东西,但以下是一个不起作用的例子:

<div class="col-md-2 mediaContainer">
  Media:
  <ul class="media" [ngSwitch]="status">
    <li *ngSwitchCase="loading"><loaders-css [loader]="'square-spin'" [loaderClass]="'my-loader'"></loaders-css></li>
    <li *ngFor="let medium of media | async"
        [class.selected] = "medium === selectedMedium"
        (click)="onSelect(medium)">
      {{medium.name}}
    </li>
  </ul>
</div>

我还将ngSwitch和/或开关案例放在列表中,但这也不起作用。我有一种感觉&#39;状态&#39;仅适用于元素本身而不是其内容,但我不确定如何设置切换值(即https://angular.io/docs/ts/latest/api/common/index/NgSwitch-directive.html),这似乎与承诺有关。有任何想法吗?鉴于我所做的事情的性质,它似乎很常见......

2 个答案:

答案 0 :(得分:4)

You can use the *ngIf directive to control the UI rendering logic , and use state variables to control the completion of request. Here is a sample.

on your component

        private loadingComplete = false;
        private isLoading = true ;
        private error;
        private media[];
        constructor(private mediaService:MediaService) {
            this.mediaService.getMedia()
                             .subscribe(
                                res =>{
                                    this.media = res;
                                    this.isLoading = false;
                                    this.loadingComplete = true;
                                },
                                err => {
                                    this.loadingComplete = true;
                                    this.error = err;
                                });
                        }

                isEmptyResult(){
                    //N.B assuming ther server returns empty array if no media found.
                    return (!this.isLoading && !this.error && this.loadingComplete && this.media && this.media.length===0);
                }
                mediaAvailable(){
                    return (!this.isLoading && !this.error && this.loadingComplete && this.media && this.media.length>0);
                }

on your template

 <div class="col-md-2 mediaContainer">
  Media:

    <li *ngIf="isLoading">
        <loaders-css [loader]="'square-spin'" [loaderClass]="'my-loader'">
        </loaders-css>
    </li>

    <p *ngIf='error'>
        Network Error.
    </p>   

    <p *ngIf='isEmptyResult()>
        No media found.
    </p>

    <ul *ngIf="mediaAvailable()" class="media" >
        <li *ngFor="let medium of media"
            [class.selected] = "medium === selectedMedium"
            (click)="onSelect(medium)">
        {{medium.name}}
        </li>
    </ul>
</div>

答案 1 :(得分:3)

I have tried showing spinner till data is available.

Please look into the following plunker.

https://plnkr.co/edit/4kSximI2a2l6SWVzqsyl?p=preview

Concerned code:-

HTML:

  <ul  >
       <div class="loader" [hidden]="myVar"></div>
        <li *ngFor="let medium of media "

        (click)="onSelect(medium)">
       {{medium.name}}
    </li>
 </ul>

CSS:-

/* Styles go here */

       .loader {
            border: 16px solid #f3f3f3; /* Light grey */
            border-top: 16px solid #3498db; /* Blue */
            border-radius: 50%;
            width: 120px;
            height: 120px;
            animation: spin 2s linear infinite;
        }

       @keyframes spin {
          0% { transform: rotate(0deg); }
         100% { transform: rotate(360deg); }
       }

Controller

          import {Component, NgModule} from '@angular/core'
          import {BrowserModule} from '@angular/platform-browser'

          export class Media {
            id: number;
           name: string;
          }

           @Component({
             selector: 'my-app',
            template: `
            <div>
             <h2>Hello {{name}}</h2>


           </div>

           <div class="col-md-2 mediaContainer">
              Media: 
           <ul  >
          <div class="loader" [hidden]="myVar"></div>
           <li *ngFor="let medium of media "

          (click)="onSelect(medium)">
           {{medium.name}}
         </li>
        </ul>
    </div>
    `,
   })
   export class App {
    name:string;
    myVar: boolean;
    media: Media[];
    constructor() {
    this.name = 'Angular2';


   setTimeout(() => {
      this.title = "Brave New World";
      this.myVar = true;

      this.media  =  [
      { id: 11, name: 'Mr. Nice' },
      { id: 12, name: 'Narco' },
      { id: 13, name: 'Bombasto' },
      { id: 14, name: 'Celeritas' },
      { id: 15, name: 'Magneta' },
      { id: 16, name: 'RubberMan' },
      { id: 17, name: 'Dynama' },
      { id: 18, name: 'Dr IQ' },
      { id: 19, name: 'Magma' },
      { id: 20, name: 'Tornado' }
      ];

       }, 2000);)
      }
    }

    @NgModule({
        imports: [ BrowserModule ],
        declarations: [ App ],
        bootstrap: [ App ]
    })
    export class AppModule {}

Please let me know in case of any query .