Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

rxjs - Angular subscription doesn't fire

I'm currently trying to make a parent component and child component.

When child component is loading data from REST, the parent should display a loading gif. Here is the code:

common.service.ts

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

    @Injectable()

    export class CommonService{
    private isLoadingSource = new Subject<boolean>();

    public isLoading$ = this.isLoadingSource.asObservable();

    setLoading(loading: boolean) {
        this.isLoadingSource.next(loading);
        console.log(loading);
    }
    }

app.component.ts

      import { Component, Inject, OnInit } from "@angular/core";
      import { NavService } from "./core/nav";
      import { CommonService } from "common.service";

      @Component({
      selector: "app-root",
      templateUrl: "./app.component.html",
      styleUrls: ["./app.component.scss"],
      providers: [
        NavService,
        CommonService
      ]
      })
      export class AppComponent implements OnInit {
      public loading: boolean = false;

      constructor(private commonService: CommonService) {
        this.commonService.isLoading$.subscribe(next => {
            this.loading = next;
            alert(next);});
      }
      }

child.component.ts

    import { Component, OnInit, ViewChild, AfterViewInit, ViewChildren, QueryList } from "@angular/core";
    import { CommonService } from "common.service";
    @Component({
      selector: "child",
      templateUrl: "./child.html",
      styleUrls: ["./child.scss"],
      providers: [
        CommonService
      ]
    })
    export class child implements OnInit, AfterViewInit {
      constructor(
        private commonService: CommonService,
      ) { }
      public beforeLoading(): void {
        this.commonService.setLoading(true);
      }
      public afterLoading(): void {
        this.commonService.setLoading(false);
      }
    }

When I run the code the console logged some true and false records, but the listener in app.component.ts doesn't receive a response.

There is no alert message popping up.

question from:https://stackoverflow.com/questions/65952448/angular-subscription-doesnt-fire

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The reason this doesn't work is because you provide the service, not as a singleton but as seperate instances per component. It is instantiated twice and thus does not share it's data.

@Injectable({
  providedIn: "root"
})

Try adding this to your service and remove the

 providers: [CommonService]

from both child and app component.

This provides the service at the root level of your application and is used as a singleton.

I've created a working stackblitz that you can look at:

https://stackblitz.com/edit/angular-ivy-wpdyv9?file=src/app/child.component.ts


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...