【问题标题】:Angular | Subscribe to multiple observables角 |订阅多个 observables
【发布时间】:2018-12-07 04:56:51
【问题描述】:

我正在尝试创建用户将要参加的活动列表。首先我得到事件键,然后我想做的是订阅每个事件并监听变化。目前只有最后一个事件有效,因为 this.eventRef 在 for 循环中被更改。

eventRef: AngularFireObject<any>


getEvents() {

const eventsGuestsLookup = this.db.object(`eventsGuestsLookup/${this.uid}`).valueChanges()

this.eventsGuestsLookupSub = eventsGuestsLookup
  .subscribe(eventKeys => {

    if (eventKeys) {
      console.log(eventKeys)
      for (const k in eventKeys) {
        if (eventKey.hasOwnProperty(k)) {

          this.eventRef = this.db.object(`events/${k}`)

          console.log(this.eventRef)

          this.eventRef.snapshotChanges().subscribe(action => {

            const key = action.payload.key
            const event = { key, ...action.payload.val() }

           this.makeEvents(event)

          })
        }
      }
    }
  })

}

我接下来要做的是获取用户的响应,并为每个状态显示某些信息。我不知道有任何其他方法可以做到这一点,所以我检查了attendingnotAttending 两个列表,如果用户有响应,我会更改事件属性。

makeEvents(event) {
console.log(event)

event.goingText = "RSVP"
event.setGoing = 'rsvp'
event.setColor = "rsvp-color"

const attending = this.db.object(`attendingLookup/${this.uid}/${event.key}`).valueChanges()

this.attendingLookupSub = attending
  .subscribe(data => {
    console.log('attending', data)
    if (data) {
      event.goingText = "ATTENDING"
      event.setGoing = 'thumbs-up'
      event.setColor = 'attending-color'
    }
  })

const notAttending = this.db.object(`not_attendingLookup/${this.uid}/${event.key}`).valueChanges()

this.notAttendingLookupSub = notAttending
  .subscribe(data => {
    console.log('not attending', data)
    if (data) {
      event.goingText = "NOT ATTENDING"
      event.setGoing = 'thumbs-down'
      event.setColor = 'not-attending-color'
    }
  })

this.events.push(event)

}

*** 编辑

const eventsGuestsLookup = this.db.object(`eventsGuestsLookup/${this.uid}`).valueChanges()
eventsGuestsLookup.subscribe(keys => {
  of(keys).pipe(
    mergeMap(keys => {
      Object.keys(keys).map(k => {
        console.log(k)
      })
      return merge(Object.keys(keys).map(k => this.db.object(`events/${k}`)))
    })
  ).subscribe(data => console.log('data', data))
})

【问题讨论】:

  • 考虑将事件存储在限定为 for 循环的变量中,而不是改变该共享属性。而不是this.eventRef =...,试试var event = ...
  • @Jonathan Wilson var 不是块作用域,因此它的作用域是封闭函数而不是 for 循环块。

标签: javascript angular rxjs


【解决方案1】:

你想要实现的是扁平化你的 observables 集合。要实现它,您可以执行以下操作:

//Dummy eventKeys observable.
const obs1$ = new BehaviorSubject({key:1, action: 'lorem'});
const obs2$ = new BehaviorSubject({key:2, action: 'lorem'});
const obs3$ = new BehaviorSubject({key:3, action: 'lorem'});

const eventKeys = {
  obs1$,
  obs2$,
  obs3$
};
// Dummy eventsGuestsLookup observable.
of(eventKeys)
.pipe(
  //eventsGuestsLookup dispatch collection of obserbable, we want to flat it.
  mergeMap(ev => {
    // We merge all observables in new one.
    return merge(...Object.keys(ev).map(k => ev[k]));
  }),
).subscribe(console.log);

重要提示ev[k] 是一个 Observable 对象。在您的情况下,您应该执行以下操作:

.map(k => this.db.object(`events/${k}`)) // will return observable.

live demo

【讨论】:

  • 嗨。谢谢你的回答,但我不明白。我得到了一些钥匙,并且必须得到相应的事件。我是否必须为每个键创建新的BehaviorSubjects 并将它们添加到对象中? eventKeys 对我来说只是一个充满键的数组。
  • 因为我手头没有你的项目,所以我不能为你的问题提供确切的答案。所以在这里我创建了BehaviorSubjects 来模拟返回 Observable 的this.db.object(events/${k})。这就是为什么我有准确的重要说明。
  • 我明白了。谢谢你的解释。我会看看我能解决什么问题。
  • 请看我的编辑。我有一些事情要发生......但它不起作用。我收到此错误Argument of type '(keys: {}) =&gt; UnaryFunction&lt;Observable&lt;{}&gt;, Observable&lt;{} | AngularFireObject&lt;{}&gt;&gt;&gt;' is not assignable to parameter of type '(value: {}, index: number) =&gt; ObservableInput&lt;{}&gt;'. 这里mergeMap(keys =&gt; {
  • 你能告诉我什么是钥匙吗?我会尽力为您提供解决方案
猜你喜欢
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
相关资源
最近更新 更多