通过http

时间:2018-12-08 14:44:30

标签: angular

有3种消耗API资源的方式可以解决这种情况。
除了,我真的不知道在什么情况下使用这3种方法所用的案例。 但是,这是下面的三个。
如果希望我们需要遵循这种方法?

第一种方法:
它正在创建一个可观察的this.articles$ = this.http.get(this._articlesUrl);,然后我们先创建*ngIf="!(articles$ | async)"然后是*ngFor="let item of articles$ | async; trabckedBy: trackElement"

export class ArticleComponent implements OnInit {

  private _articlesUrl = 'http://127.0.0.1:8000/api/articles';
  private articles$: Observable<any>;

  constructor(
    private http: HttpClient,
  ) { }

  ngOnInit() {
    this.articles$ = this.http.get(this._articlesUrl)
      .pipe(share());
  }

  trackElement(index: number, element: any) {
    return element ? element.id : null;
  }

第二种方法:

export class ArticleComponent implements OnInit {

  private _articlesUrl = 'http://127.0.0.1:8000/api/articles';
  private articles$: Observable<any>;

  constructor(
    private http: HttpClient,
  ) { }

  ngOnInit() {
    this.articles$ = this.http..get(this._articlesUrl ).pipe(map(data => data.articles)); // I dony know this syntaxe
  }

  trackElement(index: number, element: any) {
    return element ? element.id : null;
  }

然后我们先创建*ngIf="!(articles$ | async)"然后*ngFor="let item of articles$ | async; trabckedBy: trackElement"

第三种方法:

export class ArticleComponent implements OnInit, OnDestroy {

  private _articlesUrl = 'http://127.0.0.1:8000/api/articles';
  private subscription: Subscription;

  constructor(
    private http: HttpClient,
  ) { }

  ngOnInit() {
    this.subscription = this.http.get(this._articlesUrl).subscribe(
      (data) => {
        this.articles = data.articles;
      }
    );
  }

  trackElement(index: number, element: any) {
    return element ? element.id : null;
  }

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

下一步是先*ngIf="!articles",然后*ngFor="let item of articles; trabckedBy: trackElement"来解析文章。

2 个答案:

答案 0 :(得分:2)

没有一个很好。

首先,最好的通用做法是将与HTTP相关的代码放入服务中,而不是直接放入组件中。这使组件的代码更简单,更易于测试。

第一个:您没有说为什么在服务中使用share()。我认为这是因为您注意到在视图中两次使用异步管道会发送两个http请求。但这并不是修复该视图的职责,因此您不应该这样做。

第二个:您似乎不了解map()运算符的作用。它只是将源可观察到的事件转换为其他事件。在这种情况下,它将{ articles: [...] }形式的对象转换为[...]。它根本不共享可观察的东西。如果服务发回一个对象,则只需要对该对象的articles数组感兴趣。由于您在视图中使用了两次异步,因此您将两次发送http请求,这不是您想做的事情。

第三个:是正确的,但是存储订阅并取消销毁通常是没有用的:可观察到的消息在响应返回后即完成,并且当响应完成(或出错)时,订阅者将自动退订。如果您订阅了一个运行时间很长的可观察对象(如一个间隔,它永远不会完成),那将很有用。

因此,我将使用第三个代码,但删除不必要的代码。

如果您确实要使用异步管道,请确保在视图中仅使用一次:

<div *ngIf="articles$ | async as articles; else loading">
  Here's the list of articles:
  <div *ngFor="let article of articles"> ... </div>
</div>
<ng-template #loading>
  Loading articles...
</ng-template>

答案 1 :(得分:1)

@Ahmedbhs,如果您有可观察的内容,则可以

1.-在.html中直接使用|异步。

<div *ngFor="let item of articles$ | async;>...</div>

articles$:Observable<any>  //<--declare your variable
this.articles$=this.httpClient.get("your url")

请确保您将this.articles $等同于this.httpClient(可观察到)

2.-订阅并使用变量

<div *ngFor="let item of articlesData>...</div>

articlesData:any[];  //<--declare your variable
this.httpClient.get("your url").subscribe(res=>this.articlesData)

看到您订阅了this.httpClient(一个Observable),并且当您获得结果(订阅到函数中)时,您将变量“ this.articlesData”等同于调用的结果。所以您要遍历数据数组

订阅数据时,请取消订阅“良好实践”。在第一个示例中,管道异步为您服务。在第二个示例中,您可以使用为true且在ngOnAfter中等于false的变量

articlesData:any[];  //<--declare your variable
live:boolean=true;   //<---declare a variable "live"
this.httpClient.get("your url").pipe(
      takeWhile(()=>this.live==true)
      ).subscribe(res=>this.articlesData) 

ngOnAfterInit()
{
    this.live=false;
}