定义后直接订阅服务中的可观察对象
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();
})
);
在 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();
})
);