【问题标题】:Angular / TS - How to call a function from a component to a service and get a returned valueAngular / TS - 如何从组件调用函数到服务并获取返回值
【发布时间】:2019-02-25 00:08:43
【问题描述】:

我有一个调用“getUserDocInfo()”的组件,它在它自己的服务中。我将如何调用该函数,然后将返回的数据用于进一步的代码?

我的组件

 getToken(){
    this.userService.getUserDocInfo();
    // once this is called I would like to use some of the values in the returned data
  }

我的服务

getUserDocInfo() {
    this.getUserInfo().then(() => {
      this.userDoc = this.afs.doc(`users/${this.userID}`);
      this.user = this.userDoc.snapshotChanges();
      this.user.subscribe(value => {
        const data = value.payload.data();
      });
    })
  }

 async getUserInfo() {
    const user = await this.authService.isLoggedIn()
    if (user) {
      this.userID = user.uid;
    } else {
      // do something else
    }
  }

我们将不胜感激任何有关最佳实践的帮助。

【问题讨论】:

  • 您要查找的关键字是return。我强烈建议你不要将 promises 和 observables 混为一谈。学习 observables,并坚持下去。
  • 谢谢。我的问题主要是围绕如何使用返回的数据。我只想要它的一部分。我是 this.userService.getUserDocInfo().subscribe 吗?
  • 是的。但要使其正常工作,getUserDocInfo() 必须返回一个可观察对象。
  • 我总是说:“服务返回 Observables -或 Promise-,组件订阅服务”。一般来说是一个更好的方法。主要是因为您可以更改服务而无需更改组件。例如首先,您的服务可以在从 dbs 读取后从文件中读取数据。因此,您可以将多个 observables 组合在一个组件中。如果您想对某些表进行“缓存”,则服务于“可缓存”表的服务(或者如果不是对服务器的调用)。所有这些都不会强迫您更改组件

标签: angular typescript google-cloud-firestore angularfire5


【解决方案1】:

一种方法是实现一个回调,您将传递方法参数。像这样的。

getUserDocInfo(callback) {
    this.getUserInfo().then(() => {
      this.userDoc = this.afs.doc(`users/${this.userID}`);
      this.user = this.userDoc.snapshotChanges();
      this.user.subscribe(callback);
    })
  }

getToken(){
    this.userService.getUserDocInfo((value) => {
        console.log(value.payload.data());
    });
  }

您也可以返回 Observable 并在您的组件上下文中订阅它,您可以根据需要处理订阅。

import { Observable } from 'rxjs/Observable/';
import 'rxjs/add/observable/fromPromise';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';

@Injectable()
export class AlertService {

  //constructor and properties...

  getUserDocInfo(): Observable<any> {
    Observable.fromPromise(this.getUserInfo()).mergeMap(() => {
      this.userDoc = this.afs.doc(`users/${this.userID}`);
      this.user = this.userDoc.snapshotChanges();
      return this.user.map(user => user);
    });
  }
}

@Component(...)
export class MyComponent implements OnDestroy {

  subscriptions: Array<Subscription> = new Array;

  //constructor

  getToken(){
    const sub = this.userService.getUserDocInfo().subscribe((value) => {
        console.log(value.payload.data());
    });
    this.subscriptions.push(sub);
  }

  ngOnDestroy() {
    this.subscriptions.forEach(sub => sub.unsubscribe());
  }
}

【讨论】:

  • 太棒了,第一个选项有效! - 感谢您花时间给出详细的答复! - 这两者之间有任何优点或缺点吗? (我可以在几分钟内接受答案)
  • 我更喜欢第二个。因为您可以控制订阅并在不再需要时关闭它,在您的情况下,当组件通过ngOnDestroy 销毁时,我确实建议您这样做,因为如果您打开相当数量的订阅并且不要关闭它,您会遇到一些性能问题。让我编辑我的答案以向您展示我的意思。
  • 第二个不正确:你返回的是一个承诺,而不是一个可观察的。
  • snapshotChanges 返回一个 Observable,它设置为 this.userthen 返回 this.user 并且该方法返回 then 所以我确实返回了一个 Observable 或者缺少什么?
  • 确实@JBNizet 是对的。让我尽快修复它。
猜你喜欢
  • 1970-01-01
  • 2013-10-24
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2012-12-19
  • 2014-02-12
  • 1970-01-01
  • 2016-05-24
相关资源
最近更新 更多