如何将Observable中的值作为Angular 2+中的函数返回

时间:2018-01-26 14:46:42

标签: javascript angular ionic3 observable angularfire2

好的,基本上我一直在努力使用用户ID将用户详细信息存储在firebase中。

我有一个包含对象中用户ID的项目列表。我希望将此用户ID传递给类似

的函数
<div *ngFor="let item of items">
    <p>{{getUsername(item.userId)}}</p>
</div>

在应用的HTML部分。

然后使用此ID我想拉取存储在firebase中的用户名等,并将密钥作为相同的用户ID。

以下选项是我已经尝试过的东西;

选项1(只是同一组件的功能)

输出 undefined 我相信这是因为函数运行和 在订阅将数据传入之前返回username变量 它

constructor(public db: AngularFireDatabase){}

getUserName(id) {
    var username;
    this.db.object('users/' + id).valueChanges().subscribe(v => {
        username = v['username'];
    });
    return username;
}

选项2(创建服务 - 可注入,以便将其传递给对象属性)

输出我需要的内容,但它对所有列表元素显示相同

username;

constructor(public db: AngularFireDatabase){}

getUserName(id) {
    this.db.object('users/' + id).valueChanges().subscribe(v => {
        this.username = v['username'];
    });
    return this.username;
}

所以我需要的是类似于选项1但是一旦observable获取数据并将其传递给函数内部的变量,它需要返回observable中的值,因此它不会返回 undefined value。

2 个答案:

答案 0 :(得分:3)

这里一个重要的概念是Observable是异步的,所以你不能只是&#34;返回&#34;它具有正常值的价值。在返回该值之前,必须等待它emit一个值。在此处详细了解:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

对于您专门尝试做的事情,我建议您只使用Observable并使用&#39; async&#39;在模板中需要时进行管道。

getUserData(id): Observable<YourData> {
  return this.db.object('users/' + id).valueChanges();
}

然后在您的模板中,您可以执行以下操作:

<li *ngFor=let user of users"> {{ getUserData(user.id) | async }}</li>

如果您知道组件中的用户id,并且您想获取该用户的用户数据并在组件代码中使用它,您可以执行以下操作:

userData: YourData;
@Input() id: any; // provided by parent component

ngOnInit() { // OnInit lifecycle hook
  this.db.object('users/' + this.id).valueChanges().subscribe(data => this.userData = data);
}

但请记住处理订阅的清理工作。

答案 1 :(得分:0)

尝试做这样的事情:

你不能返回你订阅的值,你必须在订阅中完成所有操作,如果你有主数据,你必须在你的.ts中调用你的getUserName函数,然后创建最后一个数组所有信息,一旦你有了最终的数组,就可以在你的HTML中使用* ngFor循环。

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ModalController } from 'ionic-angular';


@IonicPage()
@Component({
  selector: 'page-restaurant-menu',
  templateUrl: 'restaurant-menu.html',
})


export class YourClass {
     public userName : String;
     public navData  : any;
     public final_array : any  

    constructor(public navCtrl: NavController, public navParams: NavParams, public) {
      this.navData = this.navParams.get('users');
      for(let user of this.navData){
          this.getUserName(user.id, user)
      }

  }


getUserName(id, user) {
    this.db.object('users/' + id).valueChanges().subscribe(v => {
        //here you have to create your final array whit the information
        this.final_array.push({user_data:user, user_name:v['username']})

    });
}


}

然后在您的HTML中,您可以使用* ngFor

<p>{{ final_array.user_name }}<p>

这是一个想法,你如何解决这个问题