【问题标题】:Angular Material 2 Spinner with Angular 4Angular Material 2 Spinner 与 Angular 4
【发布时间】:2017-08-08 17:46:27
【问题描述】:

借助 coursetro 上现有的 Angular Material 教程,我能够使用 Angular 4 和 Angular Material 控件尝试 http 和订阅场景。当我首先获取所有照片时,我看到 UI 出现滞后。因此,我想到了实现 Spinner,它给人的印象是加载数据 md-progress-spinner,但由于某种原因,spinner 没有出现,而且我也没有看到任何控制台日志,您能否建议?

spinner.service.ts:

import {Injectable} from '@angular/core';
import {Subject} from 'rxjs/Subject';


@Injectable()
export class SpinnerService {
    public status: Subject<boolean> = new Subject();
    private _active: boolean = false;

    public get active(): boolean {
        return this._active;
    }

    public set active(v: boolean) {
        this._active = v;
        this.status.next(v);
    }

    public start(): void {
        this.active = true;
    }

    public stop(): void {
        this.active = false;
    }
}

app.module.ts:

@NgModule({
    declarations: [
        AppComponent,
        SpinnerComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        BrowserAnimationsModule,
        MdButtonModule,
        MdMenuModule,
        MdCardModule,
        MdToolbarModule,
        MdIconModule,
        MdProgressSpinnerModule
    ],
    providers: [SpinnerService],
    bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts:

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    myData: Array<any>;

    constructor(private http:Http,private spinner: SpinnerService) {
        this.spinner.start();
        this.http.get('https://jsonplaceholder.typicode.com/photos')
                 .map(response => response.json())
                 .subscribe(res => this.myData = res,
                            error => console.error(error),
                            () => this.spinner.stop()
                           );
     }
}

app.component.html:

<app-spinner>Spinning...</app-spinner>

<md-toolbar color="primary">

    <span>MyCompany</span>
    <span class="example-spacer"></span>
    <button md-button [mdMenuTriggerFor]="appMenu"><md-icon>menu</md-icon> Menu</button>

</md-toolbar>

<md-menu #appMenu="mdMenu">
    <button md-menu-item> Settings </button>
    <button md-menu-item> Help </button>
</md-menu>

<md-card class="example-card" *ngFor="let data of myData; let i = index">

    <!--<md-card class="example-card" *ngFor="let data of (myData ? myData.slice(0,10): []); let i = index"> -->

    <img md-card-image src="{{ data.url }}">
    <md-card-header>
        <md-card-title>{{ data.title }}</md-card-title>
    </md-card-header>

    <md-card-actions>
        <button md-button>LIKE</button>
        <button md-button>SHARE</button>
    </md-card-actions>
</md-card>

spinner.component.ts:

 @Component({
     selector: 'app-spinner',
     templateUrl: './spinner.component.html',
     styleUrls: ['./spinner.component.css']
 })
 export class SpinnerComponent implements OnInit, OnDestroy {

     public active: boolean;

     public constructor(private spinner: SpinnerService) {
         spinner.status.subscribe((status: boolean) => {
             this.active = status;
         });
     }

     ngOnInit(){
         this.spinner.stop(); // or do it on some other event eg: when xmlhttp request completes loading data for the component
     }

     ngOnDestroy(){
         this.spinner.start();
     }

 }

spinner.component.html:

 <div *ngIf="active">
     <md-progress-spinner mode="indeterminate"></md-progress-spinner>
 </div>

请检查我在加载微调器时是否犯了任何错误,我的愿景是通过仅在app.component.html 中提到的 app-spinner 选择器在多个订阅调用中跨多个组件使用此微调器,您能否建议如果上述方法适用且需要任何更改?

【问题讨论】:

  • 在我的例子中,微调器出现了,我的微调器控件在 app.component.html --> --> 我可以看到微调器,但背景没有变灰.. 在我的情况下,如何保持微调器但背景变灰 ?你找到解决方案了吗?

标签: angular angular-material2


【解决方案1】:

你可以这样做:

使用事件 Emmitter 创建服务

   import { Injectable , EventEmitter } from '@angular/core';

   @Injectable()
   export class SpinnerService {
   public spinnerActive: EventEmitter<Boolean>;
   constructor() {
   this.spinnerActive = new EventEmitter();

   }

   activate(){
   this.spinnerActive.emit(true)
   }

   deactivate(){
   this.spinnerActive.emit(false)
   }

}

在您的 app.component.ts 中

    constructor(private http: Http , private spinnerService : SpinnerService){
     this.spinnerService.spinnerActive.subscribe(active => 
     this.toggleSpinner(active)); 
     }
    toggleSpinner(active){
      console.log("inside Toggle Spinner")
      this.activeSpinner = active
    }

您的 activeSpinner 可以在您的模板中像这样使用:

&lt;md-spinner *ngIf="activeSpinner"&gt;&lt;/md-spinner&gt;

通过activatedeactivate 服务方法激活和停用您的微调器。

要让它在任何地方都能正常工作,请确保您的微调器被抬高 (z-index) 和 position fixed,以便微调器位于已在其上方渲染的所有内容之上(如果有的话)。

【讨论】:

  • 例如,如何在我的表单顶部的叠加层中加载?谢谢
【解决方案2】:

而不是不同的方法,有一个变量,该变量直接从要实现 spinner 的组件中设置。比如

你的 spinner.ts

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-loader',
  templateUrl: './loader.component.html',
  styleUrls: ['./loader.component.css']
})
export class LoaderComponent{
  @Input() show:boolean;
}

HTML:

 <div *ngIf="show">
      <md-spinner></md-spinner>
    </div>

您想在其中使用 spinner 的组件。

<app-loader [show]="showLoader">

  </app-loader>

在您的 TS 中,只需将 showLoader 的值设置为 true/false。

【讨论】:

  • 感谢您的回答,但我的第二个查询是指在 app.component.html 中仅放置一次 app-spinner 或 app-loader 选择器,并且应该根据 spinner 服务标志加载微调器,该标志可以在多个组件中设置/重置。
  • 你可以在你喜欢的任何多个组件中使用它。 loader 组件是独立的
  • 好的,但是如果你看到我的文件或请求它的目标是让加载器组件的选择器只在应用程序组件中声明一次,并且根据需要,其余组件将不得不使用 start 或根据对服务的订阅停止微调器..
【解决方案3】:

我在DOM中得到了spinner元素,但是看不到,这是我解决的方法:

在html组件中:

<mat-progress-spinner mode="indeterminate" [diameter]="28"></mat-progress-spinner>

在 app.module.ts 中:

import { MatProgressSpinnerModule } from '@angular/material';
@NgModule({
  imports: [
    MatProgressSpinnerModule],
  exports: [
    MatProgressSpinnerModule
  ]

在 style.css 中:

@import '~@angular/material/prebuilt-themes/deeppurple-amber.css';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    • 2023-01-19
    • 1970-01-01
    • 2018-01-11
    相关资源
    最近更新 更多