首页 文章

与其他组件或服务共享可观察对象

提问于
浏览
1

订阅一个在不同组件中调用的观察者时遇到问题 .

我的Angular 4应用程序有一个导航栏,其中包含一些用户信息 . 在登录时从对服务器的http请求获得用户信息 . 这是使用LoginService管理的 . 在注销时,我们将用户设置为null .

logIn() {
  return this.http
  .get(this.apiUrl)
  .map(response => response.json())
}

logOut() {
  return Observable.of(null)
}

从登录组件中,使用该服务很容易获得用户详细信息 .

logIn() {
  this.loginService.logIn().subscribe((user) => {
    console.log('Logged in')
    this.user = user
    console.log(this.user)
  )
}

但我还需要从另一个组件中获取它们以设置导航栏中的值 . 我想我需要使用navbar组件订阅LoginService logIn()和logOut()函数,合并这些observable,如果它们中的任何一个触发事件,则更新用户 . 但我不能订阅它们,2天后我仍然坚持这个 .

I've made a plunk to show the problem . 单击登录按钮时,应设置app.component中的用户,并且在单击注销按钮时应取消设置 .

2 回答

  • 1

    我只是使用 BehaviorSubject 而不是将用户保留为 LoginService 中的属性 . 然后,您可以在需要当前用户时随时订阅它 . 然后注销只是调用 .next(null)

    看到你更新的plnkr:https://plnkr.co/edit/soeqH4IiNhcanNqxdnLS?p=preview

    login服务

    @Injectable()
    export class LoginService {
      private apiUrl = 'https://api.github.com/users/geraintanderson'
    
      user$ = new BehaviorSubject(null);
    
      constructor(
        private http: Http
      ) {}
    
      logIn() {
        return this.http
          .get(this.apiUrl)
          .map(response => response.json())
          .do(user => this.user$.next(user))
      }
    
      logOut() {
        this.user$.next(null);
      }
    }
    

    模板:

    <span *ngIf="loginService.user$ | async; else noUser; let user">
      Logged in as <b>{{ user.name }}</b>
    </span>
    <ng-template #noUser><span>Not logged in</span></ng-template>
    
  • 3

    一个更简单的解决方案是不暴露可观察对象,而只是暴露数据 . 我在这里更新了你的plunker:https://plnkr.co/edit/ilfEtmxolC16vRKRiE0q?p=preview

    服务:

    import { Injectable } from '@angular/core'
    import { Http } from '@angular/http'
    
    import 'rxjs/add/operator/map'
    
    @Injectable()
    export class LoginService {
      user;
    
      private apiUrl = 'https://api.github.com/users/geraintanderson'
    
      constructor(
        private http: Http
      ) {}
    
      logIn() {
        return this.http
        .get(this.apiUrl)
        .map(response => response.json())
        .subscribe((user) => {
          console.log('Logged in')
          this.user = user
          console.log(JSON.stringify(this.user));
        )
      }
    
      logOut() {
        this.user = null;
        console.log('Logged out')
      }
    }
    

    组件:

    import {Component, OnInit, VERSION} from '@angular/core'
    import { LoginService } from './login.service'
    
    @Component({
      selector: 'my-app',
      templateUrl: './src/app.component.html',
    })
    export class App implements OnInit {
      get user() {
        return this.loginService.user;
      }
    
      constructor(private loginService: LoginService) {
        this.angularVersion = `Angular version ${VERSION.full}`
      }
    }
    

    html:

    <div>
      <span *ngIf="user">Logged in as <b>{{user.name}}</b></span>
      <span *ngIf="!user">Not logged in</span>
      <h2>Shared services</h2><p>Created with {{angularVersion}}</p>
      <hr>
      <app-login></app-login>
    </div>
    

相关问题