【问题标题】:Data from observable not displaying来自可观察的数据不显示
【发布时间】:2017-09-08 05:37:25
【问题描述】:

在我的项目中,我在服务中使用 Observables 来保存从数据库中获取的数据。所以我在我的主要组件中订阅它。

search.service中的数据检索函数

  getData(){
    return new Observable(subscriber => {
      this.db.find({}, function(err, docs) {
        if (err) subscriber.error(err);
        subscriber.next(docs);
      });
    })
  }

在主组件中

  getData(){
    this.searchService.getData().subscribe(
      data => {
        this.datum = data;
        console.log(this.datum)},
      err => console.log("E", err)
    );
    console.log(this.datum);
  }

  ngOnInit(){
    this.getData();
  }

这是我在控制台中得到的结果

据我了解,虽然在.subscribe() 方法的上下文中,属性datum 被分配了数据库的内容,但在它之外,它仍然是未定义的。 我不明白为什么会这样,或者如何显示 DB 的内容。我发现的所有教程都表明,在我订阅 observable 并在订阅方法中分配我的组件的属性以导致 observable 传递之后,一切都应该保持这种方式,并且我应该能够在组件中轻松地显示它。

一个月左右以来我一直在为此苦苦挣扎,并且对有关 observables 的文章一无所知。好像我明白了原理,但无论如何都无法使用。

任何提示将不胜感激。

(我不想诉诸使用 Promise,因为 observables 在适用性方面似乎更普遍一些,而且学习它们似乎是一项非常有效的技能)

编辑

组件的 html 模板。

<!--The whole content below can be removed with the new code.-->
<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
    Data: {{datum}}
  </h1>

编辑 2

查看

【问题讨论】:

  • db.find() 是异步。这就是为什么它不返回它找到的值,而是将回调作为参数,以便在数据可用时通知您。因此,您不能指望在订阅您的 observable 后立即拥有数据。只有在调用观察者时,您才会拥有它们(如日志所示)。为什么它不显示是另一回事。发布组件的模板。
  • 我明白了。但是为什么 db.find() 的结果存储在属性数据中呢?在模板中,我有像 {{(datum | async)}} 这样的插值语法,但它不显示任何内容
  • 我已将此标记为重复。如果您认为不是,请发表评论,我将取消它
  • 非常相似,但不同之处在于我已经知道要记录我的结果我必须在 subscribe() 方法中调用 log 函数,但不知道如何显示结果在分配后,似乎存储结果的属性仍未定义
  • 你如何尝试显示它?如果它像{{(datum | async)}},那么您使用它是错误的,因为async 是可观察对象的管道。移除管道并像{{ datum }} 一样简单地使用它

标签: angular observable reactive-programming


【解决方案1】:

[跟随cmets中的数字;它们代表执行顺序]

getData(){
    this.searchService.getData()
        .subscribe( //1. subscrube just registers what will happen when data comes and immediately goes to next call
            this.successHandle.bind(this),//3. this will run only when data comes which might be a year from subscription
            err => console.log("E", err)
        );
    console.log(this.datum); //2. runs immediately after subscribe
  }

successHandle(data){
    this.datum = data;
    console.log(this.datum) //4. logs data when it comes
}

您的第 2 行。记录“未定义”,因为此时还没有数据。您刚刚订阅,但数据将在未来出现

【讨论】:

  • 谢谢,现在有点清楚了,但是我需要在组件中单独的函数来进行分配吗?目标是能够使用我从数据库获得的数据来填充模板。现在模板中的插值什么都不做
  • 这个答案是错误的,因为successHandle 方法中的this 不会引用组件,因此this.datum 将是未定义的。
  • 好吧,您有多种选择,从async 管道到手动解析。首先,我建议您在文档中查看:angular.io/tutorial/toh-pt4#async-services-and-promises
  • @echonax,如果不是组件,this指的是什么?
  • 它将引用successHandle 方法实例。你应该阅读:stackoverflow.com/questions/20279484/…
【解决方案2】:

在这里您正在进行异步调用,并且在从数据库中获取数据时,组件中订阅之外的console.log(this.datum); 将运行,完成后,订阅中的console.log(this.datum) 将运行。这就是 Observables 和 callBacks 的全部故事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-04
    • 2016-06-23
    • 1970-01-01
    • 2019-03-15
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多