Angular2 http.get() ,map(), subscribe() 和可观察模式——基本理解
Angular2 http.get() ,map(), subscribe() and observable pattern - basic understanding
现在,我有一个初始页面,其中有三个 link。单击最后一个 'friends' link 后,将启动相应的好友组件。在那里,
我想 fetch/get 我的朋友列表存储到 friends.json 文件中。
到现在为止一切正常。但我仍然是使用 RxJs 的 observables、map、subscribe 概念的 angular2 HTTP 服务的新手。我试图理解它并阅读了几篇文章,但在我开始实际工作之前,我不会正确理解这些概念。
这里我已经制作了 plnkr,除了 HTTP 相关的工作之外,它可以正常工作。
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- 您将可观察对象本身分配给 this.result
。当您实际上想将朋友列表分配给 this.result
时。正确的做法是:
您订阅了 observable。 .subscribe
是实际执行可观察对象的函数。它需要三个回调参数如下:
.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")}
);
通常,您会从成功回调中获取结果并将其分配给您的变量。
错误回调是不言自明的。
complete 回调用于确定您已收到最后的结果且没有任何错误。
在你的 plunker 上,complete 回调总是在成功或错误回调之后被调用。
2- 第二个错误,您在 .map(res => res.json())
上调用了 .json()
,然后在可观察对象的成功回调中再次调用了它。
.map()
是一个转换器,它将结果转换为任何你 return (在你的情况下 .json()
),然后再传递给成功回调
你应该在其中任何一个上调用一次。
概念
简而言之,Observables 处理异步处理和事件。与 promises 相比,这可以描述为 observables = promises + events。
Observables 的优点在于它们是惰性的,它们可以被取消,你可以在其中应用一些运算符(比如 map
, ...)。这允许以非常灵活的方式处理异步事物。
一个很好的示例描述了 observables 的最佳功能是将过滤器输入连接到相应的过滤列表的方法。当用户输入字符时,列表会刷新。 Observables 处理相应的 AJAX 请求并取消之前的 in-progress 请求(如果另一个请求被输入中的新值触发)。下面是对应的代码:
this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
(textValue
是与过滤器输入关联的控件)。
下面是对此类用例的更广泛描述:。
AngularConnect 2015 和 EggHead 上有两个精彩的演讲:
- Observable 与 promises - https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises
- Creating-an-observable - https://egghead.io/lessons/rxjs-creating-an-observable
- RxJS In-Depth https://www.youtube.com/watch?v=KOOT7BArVHQ
- Angular 2 数据流 - 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
正在行动
事实上,关于您的代码,您混合了两种方法 ;-) 它们如下:
自己管理可观察对象。在这种情况下,您负责调用可观察对象的 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
方法的 Returns 是可观察的而不是结果(与承诺的方式相同)。
让我们通过 Angular 模板 管理可观察对象。您还可以利用 async
管道隐式管理可观察对象。在这种情况下,不需要显式调用 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 方法解析它。直接我们可以像下面这样使用
http.get('friends.json').subscribe(result => this.result =result);
现在,我有一个初始页面,其中有三个 link。单击最后一个 'friends' link 后,将启动相应的好友组件。在那里, 我想 fetch/get 我的朋友列表存储到 friends.json 文件中。 到现在为止一切正常。但我仍然是使用 RxJs 的 observables、map、subscribe 概念的 angular2 HTTP 服务的新手。我试图理解它并阅读了几篇文章,但在我开始实际工作之前,我不会正确理解这些概念。
这里我已经制作了 plnkr,除了 HTTP 相关的工作之外,它可以正常工作。
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- 您将可观察对象本身分配给 this.result
。当您实际上想将朋友列表分配给 this.result
时。正确的做法是:
您订阅了 observable。
.subscribe
是实际执行可观察对象的函数。它需要三个回调参数如下:.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")}
);
通常,您会从成功回调中获取结果并将其分配给您的变量。
错误回调是不言自明的。
complete 回调用于确定您已收到最后的结果且没有任何错误。
在你的 plunker 上,complete 回调总是在成功或错误回调之后被调用。
2- 第二个错误,您在 .map(res => res.json())
上调用了 .json()
,然后在可观察对象的成功回调中再次调用了它。
.map()
是一个转换器,它将结果转换为任何你 return (在你的情况下 .json()
),然后再传递给成功回调
你应该在其中任何一个上调用一次。
概念
简而言之,Observables 处理异步处理和事件。与 promises 相比,这可以描述为 observables = promises + events。
Observables 的优点在于它们是惰性的,它们可以被取消,你可以在其中应用一些运算符(比如 map
, ...)。这允许以非常灵活的方式处理异步事物。
一个很好的示例描述了 observables 的最佳功能是将过滤器输入连接到相应的过滤列表的方法。当用户输入字符时,列表会刷新。 Observables 处理相应的 AJAX 请求并取消之前的 in-progress 请求(如果另一个请求被输入中的新值触发)。下面是对应的代码:
this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
(textValue
是与过滤器输入关联的控件)。
下面是对此类用例的更广泛描述:
AngularConnect 2015 和 EggHead 上有两个精彩的演讲:
- Observable 与 promises - https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises
- Creating-an-observable - https://egghead.io/lessons/rxjs-creating-an-observable
- RxJS In-Depth https://www.youtube.com/watch?v=KOOT7BArVHQ
- Angular 2 数据流 - 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
正在行动
事实上,关于您的代码,您混合了两种方法 ;-) 它们如下:
自己管理可观察对象。在这种情况下,您负责调用可观察对象的
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
方法的Returns 是可观察的而不是结果(与承诺的方式相同)。
让我们通过 Angular 模板 管理可观察对象。您还可以利用
async
管道隐式管理可观察对象。在这种情况下,不需要显式调用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 方法解析它。直接我们可以像下面这样使用
http.get('friends.json').subscribe(result => this.result =result);