Angular2 http.get(),map(),subscribe()和可观察模式 – 基本理解

现在,我有一个初始页面,我有三个链接。 一旦你点击最后的“朋友”链接,适当的朋友组件就开始了。 在那里,我想获取/获取我的朋友列表进入friends.json文件。 直到现在一切工作正常。 但我仍然是使用RxJs的observables,map,订阅概念的angular2的HTTP服务的新手。 我试着去理解它并阅读了一些文章,但是直到我开始实际工作之前,我不能正确地理解这些概念。

这里我已经做了除了HTTP相关的工作之外的plnkr。

Plnkr

myfriends.ts

import {Component,View,CORE_DIRECTIVES} from 'angular2/core'; import {Http, Response,HTTP_PROVIDERS} from 'angular2/http'; import 'rxjs/Rx'; @Component({ template: ` <h1>My Friends</h1> <ul> <li *ngFor="#frnd of result"> {{frnd.name}} is {{frnd.age}} years old. </li> </ul> `, directive:[CORE_DIRECTIVES] }) export class FriendsList{ result:Array<Object>; constructor(http: Http) { console.log("Friends are being called"); // below code is new for me. So please show me correct way how to do it and please explain about .map and .subscribe functions and observable pattern. this.result = http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result =result.json()); //Note : I want to fetch data into result object and display it through ngFor. } } 

请正确引导和解释。 我知道这对许多新开发者来说是非常有益的。

这是你出错的地方:

 this.result = http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result =result.json()); 

它应该是:

 http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result =result); 

要么

 http.get('friends.json') .subscribe(result => this.result =result.json()); 

你犯了两个错误:

1-您将observable自己分配给this.result 。 当你真的想把这个朋友列表分配给this.result 。 正确的方法是:

  • 你订阅可观察的。 .subscribe是实际执行observable的函数。 它需要三个callback参数如下:

    .subscribe(success, failure, complete);

例如:

 .subscribe( function(response) { console.log("Success Response" + response)}, function(error) { console.log("Error happened" + error)}, function() { console.log("the subscription is completed")} ); 

通常,您从成功callback中获取结果并将其分配给您的variables。 错误callback是不言自明的。 完整的callback用于确定您已经收到最后的结果,没有任何错误。 在你的plunker上,完成的callback将总是在成功或者错误callback之后被调用。

2-第二个错误是,你在.map(res => res.json())调用了.map(res => res.json()) ,然后你在observable的成功callback中再次调用它。 .map()是一个转换器,它会将结果转换成任何你返回的结果(在你的情况.json() ),然后它传递给成功的callback,你应该在它们中的任何一个上调用它。

概念

简而言之,观察对象就是asynchronous处理和事件。 相比于承诺,这​​可以被描述为observables = promises + events。

可观察到的优点是它们很懒,可以取消,可以在其中应用一些运算符(如map ,…)。 这允许以非常灵活的方式处理asynchronous事件。

描述最佳观察能力的很好的例子是将filterinput连接到相应的过滤列表的方式。 当用户input字符时,列表被刷新。 Observable处理相应的AJAX请求,如果input中的新值触发另一个请求,则取消先前的正在进行的请求。 这里是相应的代码:

 this.textValue.valueChanges .debounceTime(500) .switchMap(data => this.httpService.getListValues(data)) .subscribe(data => console.log('new list values', data)); 

textValue是与filterinput相关的控件)。

下面是这种用例的更广泛的描述: 如何看Angular 2中的表单变化? 。

在AngularConnect 2015和EggHead上有两个很棒的演讲:

克里斯托夫·布格多夫(Christoph Burgdorf)也撰写了一些关于这个主题的精彩博客

在行动

实际上关于你的代码,你混合了两种方法;-)这里是他们:

  • 用你自己的方式来pipe理观测值 。 在这种情况下,您有责任调用observable上的subscribe方法,并将结果分配给组件的一个属性。 然后,您可以在视图中使用此属性来遍历集合:

     @Component({ template: ` <h1>My Friends</h1> <ul> <li *ngFor="#frnd of result"> {{frnd.name}} is {{frnd.age}} years old. </li> </ul> `, directive:[CORE_DIRECTIVES] }) export class FriendsList implement OnInit, OnDestroy { result:Array<Object>; constructor(http: Http) { } ngOnInit() { this.friendsObservable = http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result = result); } ngOnDestroy() { this.friendsObservable.dispose(); } } 

    getmap方法的返回值都是可观察值而不是结果(与promise相同)。

  • 让我们通过Angular模板来pipe理observable 。 您还可以利用asyncpipe道来隐式pipe理observable。 在这种情况下,不需要显式调用subscribe方法。

     @Component({ template: ` <h1>My Friends</h1> <ul> <li *ngFor="#frnd of (result | async)"> {{frnd.name}} is {{frnd.age}} years old. </li> </ul> `, directive:[CORE_DIRECTIVES] }) export class FriendsList implement OnInit { result:Array<Object>; constructor(http: Http) { } ngOnInit() { this.result = http.get('friends.json') .map(response => response.json()); } } 

你可以注意到,观察者是懒惰的。 所以相应的HTTP请求只会被一个监听器调用,并且使用subscribe方法附加在它上面。

您还可以注意到, map方法用于从响应中提取JSON内容,然后在可观察处理中使用它。

希望这可以帮助你,蒂埃里

 import { HttpClientModule } from '@angular/common/http'; 

HttpClient API是在4.3.0版本中引入的。 它是现有的HTTP API的演变,并有它自己的包@ angular / common / http。 最显着的变化之一就是现在响应对象默认是JSON,所以不需要再用map方法parsing它了。

 http.get('friends.json').subscribe(result => this.result =result);