以下组件的代码来自我正在创建的Angular 6 Web应用程序。该应用程序显示一个具有CRUD功能的表。我有一个名为GetDBValuesService的Angular服务,它连接到数据库并使用DBValues()来检索数组(每个内部数组包含数据库中给定行的值)。然后我的代码收集'Number'属性等于10的行。然后我的EventEmitter dataItems使用这些行,这允许它们显示在我的网页的CRUD表中。
我创建了另一个名为DataService的Angular服务,它从另一个组件接收一个整数值,并将该值发送给所显示的组件(在订阅之后)。我在以下代码中订阅了此服务,并让gotdata(在此组件中声明的public var)的实例接收服务的值。但是,当我尝试在该订阅之外使用此实例(以替换上述硬编码的10)时,此.got数据未定义。
如何修改我的代码,以便我可以使用GetDBValuesService服务中DataService服务提供的值?目前,由于硬编码10,下面的代码确实有效,但如果删除该行则不行。感谢您抽出时间来阅读。
这是我的CRUD组件的一部分:
refresh = () => {
this.DataService.DataID$.subscribe((data) => {
this.gotdata = data;
console.log(this.gotdata); //10 (value from console)
});
console.log(this.gotdata); //undefined (value from console)
this.gotdata = 10; //hardcoded value allows further functionality, will be removed when this.gotdata retains its value from the above subscription
if (this.gotdata != null) {
this.GetDBValuesService.DBValues().subscribe((result) => {
var a = 0;
for (var i = 0; i < result.length; i++) {
if (result[i].Number == this.gotdata) {
this.info[a] = result[i];
a = a + 1;
}
}
this.dataItems.next(this.info); //sets rows to be displayed in the web page's table (used by component's HTML file)
});
}}
this.gotdata
未定义,因为数据尚未解决。
refresh = () => {
this.DataService.DataID$.subscribe((data) => {
this.gotdata = data;
console.log(this.gotdata); //10 (value from console)
if (this.gotdata != null) {
this.GetDBValuesService.DBValues().subscribe((result) => {
var a = 0;
for (var i = 0; i < result.length; i++) {
if (result[i].Number == this.gotdata) {
this.info[a] = result[i];
a = a + 1;
}
}
this.dataItems.next(this.info); //sets rows to be displayed in the web page's table (used by component's HTML file)
});
}}
});
或者您可以在完全回调中将其置于订阅内:
this.service.subscribe((data) => {
// code here
},
(error) => console.error(error),
() => {
// do stuff.
});
问题在于,在您调用console.log(...)
和下面的代码时,来自dataID$
observable的数据仍在向您发送。 (Why do u need to work with observables?)
对此最好的方法是使用RXJS switchMap
运算符(what is switchMap?)。因为我看到你想订阅第一个observable
,然后订阅另一个observable
。所以它可以这样做:
refresh = () => {
this.DataService.DataID$.pipe(switchMap(data: any) => {
if (data) {
this.gotdata = data;
return this.GetDBValuesService.DBValues();
} else {
return of(null); // if 'data' are null, return "empty" observable
}
})).subscribe((result: any) => {
if (!result) {
return; // return if 'result' is null (so the code bellow won't be executed)
}
var a = 0;
for (var i = 0; i < result.length; i++) {
if (result[i].Number == this.gotdata) {
this.info[a] = result[i];
a = a + 1;
}
}
this.dataItems.next(this.info);
});