Using subjects in Angular 2

半世苍凉 提交于 2020-02-03 10:46:46

问题


My main.service.ts

@Injectable()
export class AppService{
  private mainSource = new Subject<boolean>();
  main$ = this.mainSource.asObservable();
}

My app.component.ts

constructor(private appService: AppService){
  this.appService.main$.subscribe(
  working => {this.appService.main$(false);}
}

ngOnInit(){
    if (this.appService.main$){alert("Tio");}
}

My app.component returns a Cannot invoke an expression whose type lacks a call signature error. And my OnInit alert fires regardless of whether or not the conditions have actually been met. In this case they have not.

Subscriptions are still quite foreign to me, so I'm not clear on exactly what I should be doing here. I want to set my main$ to an initial value of false. And when my page is loaded, I would like it to alert only if it is true.


回答1:


If you want to change values on a Subject it is best to create a separate method for that. In this case I added a setWorking method to change the Subject's boolean value.

Next, the component subscribes to the Subject (which is returned as an Observable) and listens to changes to the value.

If the value changes, the callback function inside the subscribe block will be invoked.

Service

@Injectable()
export class AppService{
  private mainSource = new Subject<boolean>();
  main$ = this.mainSource.asObservable();

  setWorking(isWorking: boolean) {
    this.mainSource.next(isWorking);
  }
}

Component

private subscription: Subscription

constructor(private appService: AppService){ }

ngOnInit(){

  this.appService.setWorking(false);

  this.subscription = this.appService.main$.subscribe(isWorking => {
    if (isWorking) { alert("Tio"); }
  }
}

ngOnDestroy() {
    this.subscription.unsubscribe();
}

At last, you could add a this.appService.setWorking(true); function call after the subscription, to have the alert show up.

PS: I have added the ngOnDestroy part, since the subscription is not automatically cleared when navigating away and thus would create a memory leak. You need to import Subscription from rxjs/Subscription.




回答2:


The problem is, you are subscribing in the constructor. So you do not know when the result comes, because it is async. In the meantime, the constructor finished immediately and the OnInit is invoked.

I don't know how your service looks like, but it would be the best if you also subscribe to an event in the OnInit method.



来源:https://stackoverflow.com/questions/40337891/using-subjects-in-angular-2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!