以下组件的代码来自我正在创建的Angular 6 Web应用程序。该应用程序显示具有CRUD功能的表。我有一个名为GetDBValuesService的Angular服务,该服务已连接到数据库并使用DBValues()来检索数组数组(每个内部数组都包含数据库中给定行的值)。然后,我的代码收集了“数字”属性等于10的行。这些行然后由我的EventEmitter数据项使用,这使它们可以显示在我的网页的CRUD表中。
我创建了另一个名为DataService的Angular服务,该服务从另一个组件接收一个整数值,并将该值发送到所示的组件(在订阅之后)。我在以下代码中订阅了此服务,并让gotdata实例(在此组件中声明了一个公共var)接收该服务的值。但是,当我尝试在该订阅之外使用该实例(以替换上述的硬编码10)时,this.gotdata是未定义的。
如何修改代码,以便可以在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)
});
}}
答案 0 :(得分:0)
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.
});
答案 1 :(得分:0)
问题在于,当您调用console.log(...)
和下面的代码时,来自dataID$
观察对象的数据仍在传送给您。 (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);
});