2

我创建了一个加载的微调器组件为我角4应用在AJAX调用中要显示,但我有一个订制了BehaviorSubject显示它的麻烦。装载微调使用rxjs BehaviorSubject

这个问题是关系到how to show a spinner till the time data recieved from the server in angular2但不重复(因为我想用一个可重用的组件来做到这一点),并Angular 2 + RxJS BehaviorSubject subscribe call not working(虽然我不认为我的代码和接受的答案之间有什么不同。我错过了什么? )

我基本上遵循本教程https://hassantariqblog.wordpress.com/2017/03/22/angular2-using-custom-loader-spinner-as-service-in-angular-2-application/

下面是我的一些代码:

app.modules.ts

import {AppComponent} from './app.component'; 
import {AppRoutingModule} from './app-routing.module'; 
import {SomeComponent} from './some.component'; 
import {LoaderComponent} from './loader/loader.component'; 
import {LoaderService} from './loader/loader.service'; 

@NgModule({ 
    declarations: [ 
     AppComponent, 
     LoaderComponent, 
     SomeComponent 
    ], 
    imports: [ 
     BrowserModule, 
     NoopAnimationsModule, 
     AppRoutingModule 
    ], 
    providers: [ 
     LoaderService 
    ], 
    bootstrap: [AppComponent] 
}) 
export class AppModule { 
} 

app.component.html

<router-outlet></router-outlet> 
<app-loader></app-loader> 

loader.component.html

<div class="loader" *ngIf="isLoading"></div> 

loader.component.ts

import {Component, OnInit} from '@angular/core'; 
import {LoaderService} from './loader.service'; 

@Component({ 
    selector: 'app-loader', 
    templateUrl: 'loader.component.html', 
    providers: [LoaderService] 
}) 

export class LoaderComponent implements OnInit { 
    isLoading: boolean; 

    constructor(private loaderService: LoaderService) { 
    } 

    ngOnInit() { 
     this.loaderService.status.subscribe((val: boolean) => { 
      this.isLoading = val; 
     }); 
    } 
} 

loader.service.ts

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

@Injectable() 
export class LoaderService { 
    public status: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false); 

    display(value: boolean) { 
     console.log('LoaderService.display ' + value); 
     this.status.next(value); 
    } 
} 

在一些服务的方法,它的AJAX调用

constructor(private http: Http, private loaderService: LoaderService) { 
} 

getSomeStuff(): Observable<SomeItem[]> { 
    // show the loading spinner 
    this.loaderService.display(true); 

    const content = this.http.get(this.apiUrl) 
     .map(this.extractData); 

    content.subscribe(
     () => { 
      // hide the loading spinner 
      this.loaderService.display(false); 
     } 
    ); 

    return content; 
} 

问题是,装载机永远不会被显示,因为isLoading永远不会设置为true。控制台输出:

​​

于是订阅了loaderService,改变的isLoading在loader.component.ts初始化组件时只被调用一次,值。但据我了解BehaviorSubject应该工作,它应该被调用,只要LoaderService.status改变。为什么不?我究竟做错了什么?

+0

从'LoaderComponent'中移除'providers:[LoaderService]'。 – cartant

+0

@cartant真棒!解决了它!非常感谢!你可以提交它作为答案,所以我可以接受它吗?另外,你能解释为什么这解决了这个问题吗? – masterfloda

回答

3

的问题是由于该行LoaderComponent

providers: [LoaderService] 

通过使用组件级的供应商指定服务,你通知角的组件接收业务的自己的实例 。这不是你想要的;你想共享模块级的实例。

只需从LoaderComponent中删除该行,以便使用该服务的单个实例。

+0

再次感谢!这是非常有意义的,因为我应该使用的是来自模块提供者的实例。 – masterfloda