Angular 2: how to share one service among several

2019-09-07 22:35发布

问题:

I have some service in my angular application like this to store the status of user:

public activeUser = new BehaviorSubject(null);

I do the follow:

Go to the component A and in constructor I have subscribed on this Subject (auth is service, which has been imported):

    this.auth.activeUser.subscribe((status) => {
        console.log("subscribe >>>", status);
        this.isAuth = status;
    });

In another method of this components I do this:

this.auth.activeUser.next(true);

if user login successfully, and set false if some troubles.

Greate, it works, I have got console output.

But I have another component, which must use activeUser status. In this component I imported service and do the follow:

ngOnInit() { 
       this.auth.activeUser.subscribe(
          (userStatus:boolean) => {
              this.isAuth = userStatus;
              console.log("this is foo HomeComponent", this.isAuth);
          }
      );
      console.log("home activeUser", this.auth.activeUser);
  }

I consider that when in first component Subject gets next(true) or next(false) I have to see this is foo HomeComponentin console, but it's not true.

I found this answer Subscribe method don't react to changes [Angular 2]

and according to it I have done the follow:

  1. Go to app.module.ts
  2. Imported service
  3. Add service to providers[]

Hmmm, I hoped that my problem will be soled. But no. I returned to my second component and removed the import with service. But now I can't compile the code:

this.auth.activeUser.subscribe 

where auth is injected service. I have even restarted webpack, but anyway fails. Thanks you for help.

Full second component is there:

import {Component, OnInit} from '@angular/core';
import {AuthService} from "../../platform/auth.service";
import {Observable} from "rxjs";


@Component({
    selector: 'home-page',
    templateUrl: 'home.component.html',
    styleUrls:['home.component.scss']

})

export class HomeComponent  implements OnInit {
    public isAuth: boolean;
    constructor(private auth: AuthService) {
        this.isAuth = true;
    }

   ngOnInit() { 
       this.auth.activeUser.subscribe(
          (userStatus:boolean) => {
              this.isAuth = userStatus;
              console.log("this is foo HomeComponent", this.isAuth);
          }
      );
      console.log("home activeUser", this.auth.activeUser);
  }

}

My app.module.ts

 import {AuthService} from "./platform/auth.service";

@NgModule({
    imports: [
        BrowserModule,
        // CommonModule,
        ReactiveFormsModule,
        routing,
        ModalModule,
        NgbModule,
        HttpModule
    ],
    declarations: [
        AppComponent,
        HomeComponent
    ],

    providers: [
        appRoutingProviders, AuthService
    ],
    bootstrap: [ AppComponent]
})
export class AppModule { }

My service:

@Injectable()
export class AuthService {


    public activeUser = new BehaviorSubject(null);

    constructor(private http: Http, private interaction:InteractionService) {

    }
}

回答1:

I think what you need is a ReplaySubject. This will replay the last event that was on the stream when a new consumer subscribes. Create one like this:

   // 1 is the amount of events to replay when subscribed
   new ReplaySubject<boolean>(1); 

You can use it the same way you used the BehaviourSubject