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上有两个很棒的演讲:
- Observables vs promises – https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises
- 创build一个可观察的 – https://egghead.io/lessons/rxjs-creating-an-observable
- RxJS深入https://www.youtube.com/watch?v=KOOT7BArVHQ
- Angular 2数据stream – https://www.youtube.com/watch?v=bVI5gGTEQ_U
克里斯托夫·布格多夫(Christoph Burgdorf)也撰写了一些关于这个主题的精彩博客
- http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
- http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
在行动
实际上关于你的代码,你混合了两种方法;-)这里是他们:
-
用你自己的方式来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(); } }
get
和map
方法的返回值都是可观察值而不是结果(与promise相同)。 -
让我们通过Angular模板来pipe理observable 。 您还可以利用
async
pipe道来隐式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);