我有这样的东西
getFieldsRemote(){
let fields: FormfieldBase<any>[] = [];
this.http.get('http://localhost:8080/api/getFields').subscribe(
data =>{
// code to push objects from data to fields variable declared above
}
}
)
return fields;
}
现在我面临的问题是,每当我从其他组件中调用此getFieldsRemote()
方法时,我都会得到一个空白数组。
我知道发生这种情况是因为Subscribe方法是异步的,因此它在后台运行,并且在执行内部Subscribe的代码段之前,控件会到达return语句。但是,我需要此函数以某种方式在subscribe方法完成后返回数据。在组件端订阅数据不是一种选择。请告诉我这里的解决方案。
答案 0 :(得分:2)
如果您确实要避免从组件中进行订阅,则可以将方法标记为async并等待http调用的响应。
async getFieldsRemoteAsync(){
let fields = await this.http.get('http://localhost:8080/api/getFields').toPromise();
return fields;
}
请注意,如果执行此操作,则还需要将Consumer方法标记为async,并且需要等待调用:
await getFieldsRemoteAsync();
答案 1 :(得分:0)
如果订阅不是一种选择,而您想以可观察的方式进行订阅,那么此问题将无法解决。您需要订阅组件才能获取数据,但是最好在模板中使用async
管道。这样,清理组件时,Angular会清理订阅。
getFieldsRemote
方法应通过以下方式返回Observable<FormfieldBase<any>>[]
:
import { Observable } from 'rxjs';
getFieldsRemote(): Observable<FormfieldBase<any>>[] {
return this.http.get('http://localhost:8080/api/getFields');
}
此外,请尝试避免键入any
并编写一个接口。然后在组件中,将getFieldsRemote()
的结果分配给属性fields
。
@Component({
...
})
export class ExampleComponent implements OnInit {
fields: Observable<FormfieldBase<any>>;
constructor(private service: ExampleService) {}
ngOnInit(): void {
this.fields = this.service.getFieldsRemote();
}
}
然后在您的模板中执行
<div *ngFor="let field of fields">
<!-- Do something with your field -->
</div>
如果问题是您的getFieldsRemote
方法将由多个组件调用,并且您希望共享结果(不进行多次http调用),请查看share
或{{1} } rxjs运算符。
例如:
shareReplay
但是您可能需要详细说明为什么“在组件端订阅数据不是一种选择。” ,因为这是一种明确的代码味道。
答案 2 :(得分:0)
您必须在组件内部订阅方法:
如果apiservice具有如下方法:
public getCustomer(customer: Customer){
return this.httpClient.get(`${this.apiURL}/customers/`,customer);
}
像这样在组件内部使用它:
this.apiService.getCustomer(customer).subscribe((res)=>{
console.log("get a customer", res);
});
注意:apiservice中的createCustomer返回一个可观察的
答案 3 :(得分:0)
如果您不想担心订阅,可以简单地变成一个承诺并使用async / await
async getFieldsRemote(){
let fields: FormfieldBase<any>[] = [];
const data = await this.http.get('http://localhost:8080/api/getFields').toPromise()
// do what you want with the data
return fields
}