Angular 5 - 管理服务器请求

Angular 5 - Manage right the server request

我听说建议通过服务(而不是通过组件)发出服务器请求,以便函数的请求可以(由其他组件)重用。最后,我们需要组件中的服务器响应。

我的问题是从组件调用服务以获取数据的最佳做法是什么。我问是因为 http 请求将由 Observable 执行,这意味着它是异步操作。

所以,如果我会做这样的事情:

//data.component.ts
  const data = this.httpService.getDataFromTheServer();

//httpService.service.ts
  getDataFromTheServer(){
       return this.http.post(url).map(
         res=>res.json())
       }

数据永远不会进入组件的变量。

我对这个问题的解决方案是在另一个 "Subject" 中使用。像这样:

 //data.component.ts     

 this.httpService.getDataFromTheServer()
 this.httpService.getData.subscribe(res => {
    const data = res;
}

//httpService.service.ts

   public getData = new Subject();

  getDataFromTheServer(){
       return this.http.post(url).map(
         res=> this.getData.next(res.json()))
       }

像这样分叉就好了。但我不确定这是否是解决此问题的最佳做法。

有人有其他想法吗?多谢!

更新

感谢所有受访者。我知道我可以在我的组件中这样做:

this.httpService.getDataFromTheServer().subscribe...

但我想知道我是否可以更多地清洁我的组件,并且只用这个:

const data = this.httpService.getDataFromTheServer()

或者是否有其他清洁组件的方法?或者我对建议 "make the server requests via services" 的理解还不够? 我很乐意更清楚地解释。

你可以这样做:

//data.component.ts
this.httpService.getDataFromTheServer().subscribe((data) => {
   //assign your data here
});

//httpService.service.ts
getDataFromTheServer(){
   return this.http.post(url);
}

因为 this.http.post 正在返回一个 Observable<any>,您需要订阅它。

当然你的第一个解决方案是行不通的。这是因为 "this.http.post" 方法返回的不是请求数据,而是可观察对象。所以你需要做的是订阅你的对象:)

//data.component.ts
const data = this.httpService.getDataFromTheServer();
data.subscribe(res => console.log(res)); // or just bind res to any other variable

//httpService.service.ts
  getDataFromTheServer(){
     return this.http.post(url).map(
       res=>res.json())
     }

此解决方案还使您能够取消订阅 Observale

ngOnDestroy() {
  this.data.unsubscribe();
}

最后,您真的不需要将服务方法绑定到任何变量。你可以简单地这样做:

//data.component.ts
ngOnInit() {
  this.httpService.getDataFromTheServer()
  .subscribe(res => myVariable = res) // binding response from server to variable
}

//httpService.service.ts
  getDataFromTheServer(){
     return this.http.post(url)
     .map(res=>res.json())
   }

// 编辑答案

理论上可以,但我不推荐。如果你想让你的组件保持清晰,就使用异步管道

这样做:

// component.html

<ul>
  <li *ngFor="let item of (items | async)">
</ul>
// or if its not an array
<h1>{{ item | async }}</h1>

// component.ts

public items;

ngOnInit() {
  this.items = this.httpService.getDataFromTheServer();
}

// service.ts

getDataFromTheServer(){
   return this.http.post(url).pipe(map(res => res.json());
}