定义后直接订阅服务中的可观察对象

Subscribe to an observable in a service directly after defining it

在 Angular 服务的构造函数中,我正在创建一个我需要直接订阅的可观察对象(无内部订阅)。怎么做? 特别是,在下面的第一段代码中,我有变量 data.id.

this.current_trainee = this.db.collection('Users', ref => ref.where(
  'email', '==',  'EXAMPLE'  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
);

现在我想直接订阅它,以便在下面的 doc(data.id)" 中使用它:

 this.trainees = this.db.collection('Users').doc( data.id ).collection('Trainings_taken').snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
);

我尝试通过以下方式订阅:

   this.current_trainee.subscribe(data => this.user_doc_id = data.id );

其中 user_doc_id 作为空字符串启动。但它不起作用,因为 user_doc_id 保持为空字符串。有什么建议吗?提前致谢!

所以根据大家的讨论,我做了一个很简单的例子。这里的要点是你需要链接你的第一个响应(它给你 data.id)并使用它直接调用第二个 db 函数(而不是使用 2 个变量)。正如我之前提到的,原因是,您对数据库进行 异步 调用以获取您的 ID。这将在稍后的某个时间点到达,只有到那时您才能使用此 ID 拨打电话。在您当前的代码中,您只是立即调用函数 this.db.collection('Users').doc( data.id )..} 同步 将不起作用。

我没有使用 flatMap 因为你没有内部可观察对象(我认为是这种情况)

import { of, Observable } from 'rxjs';
import { mergeMap,map } from 'rxjs/operators';

/**
 * Assume this is the response of the 
 * this.db.collection('Users', ref => ref.where(
 * 'email', '==',  'EXAMPLE'  )).snapshotChanges()
 * i.e an observable output 
 * and data_id is equivalent to data.id in your  
 */
const source = of({data_id: 0}, {data_id:1 },{data_id:2});

/**
 * Now if the data_id is the index to this array, in your case : you need the 
 * data.id to make a call to the `DB` to retrieve the trainees
 */
const db2 = ['a','b','c'];

//use map to get the ID you need and then directly call the db to retrieve trainees, in this case it will return you another observable
const example = source.pipe(map((e,i) =>  of(test(e.data_id))));

// subscribe to the observable and do your action
const subscribe = example.subscribe((val) => console.log(val));

function test(value) {
  return (db2[value]);
}

Stackblitz给你玩玩

所以在一天结束时,看看下面什么对我有用。它不是很优雅,因为部分代码会重复,但它有效,我想结束这个问题。谢谢@dream88!

this.current_trainee = this.db.collection('Users', ref => ref.where(
  'email', '==',  aux  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  })
  );

this.individual_trainings = this.db.collection('Users', ref => ref.where(
  'email', '==',  aux  )).snapshotChanges().pipe(
  map(changes => {
    return changes.map(a => {
      const data = a.payload.doc.data() as Trainee;
      data.id = a.payload.doc.id;
      return data;
    });
  }),
  switchMap((data) => {
    console.log(data);
    console.log(data[0].id);
    return this.aux2 = this.db.collection('Users').doc(data[0].id).collection('Trainings_taken').valueChanges();
  })
  );