这看起来很简单,但我找不到任何解决方法。 我尝试做的是在加载异步列表时使用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),这似乎与承诺有关。有任何想法吗?鉴于我所做的事情的性质,它似乎很常见......
答案 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 .