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

How to use CSS spinner in Angular2 while loading asynchronous list?

这看起来很简单,但我找不到任何解决方法。 我想要做的是在异步列表加载时有一个 CSS spinner/loader。我已经尝试了各种方法,包括尝试使用 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 and/or 开关盒放在列表中,但这也不起作用。我觉得 'status' 只适用于元素本身而不适用于它们的内容,但我也不确定如何设置开关值(即 https://angular.io/docs/ts/latest/api/common/index/NgSwitch-directive.html),这似乎与承诺可能。有任何想法吗?考虑到我正在做的事情的性质,这似乎很常见......

您可以使用 *ngIf 指令来控制 UI 渲染逻辑,并使用状态变量来控制请求的完成。 这是一个示例。

在你的组件上

        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);
                }

在您的模板上

 <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>

我已经尝试显示微调器直到数据可用。

请看下面的插件

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

关注代码:-

HTML:

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

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

CSS:-

/* 样式放在此处 */

       .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); }
       }

控制器

          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 {}

如有任何疑问,请告诉我。