Angular 角度观测值与Http
我的大脑很难用角度来观察。我来自PHP世界,那里的东西绝对不是异步的 我有一个组件,它只显示一般主题的消息列表。现在,我有一个所有消息都属于的主题。如果主题不存在,那么应该创建它。消息和主题调用都是通过RESTAPI完成的 在非异步世界中,我会按顺序编程。消息服务将查看主题是否存在。如果没有,则让主题服务创建它。获得主题后,它将获取该主题中的所有消息 我知道你订阅了一个可观察的,但是当需要一系列事情按顺序发生时会发生什么呢?下面是一个非常简单的例子,当一次调用时更新英雄列表 组件Angular 角度观测值与Http,angular,observable,Angular,Observable,我的大脑很难用角度来观察。我来自PHP世界,那里的东西绝对不是异步的 我有一个组件,它只显示一般主题的消息列表。现在,我有一个所有消息都属于的主题。如果主题不存在,那么应该创建它。消息和主题调用都是通过RESTAPI完成的 在非异步世界中,我会按顺序编程。消息服务将查看主题是否存在。如果没有,则让主题服务创建它。获得主题后,它将获取该主题中的所有消息 我知道你订阅了一个可观察的,但是当需要一系列事情按顺序发生时会发生什么呢?下面是一个非常简单的例子,当一次调用时更新英雄列表 组件 export
export class NotificationListComponent implements OnInit {
constructor(private _notificationService:NotificationService) {
}
***
ngOnInit() {
this.getNotifications();
}
getNotifications() {
this._notificationService.getNotifications()
.subscribe(
notifications => this.notifications = notifications,
error => this.errorMessage = <any>error);
}
虽然我不确定是否理解您的问题,但可能是
Observable。选择many
和Observable。然后选择do/when
可以帮助您
在您的情况下,我认为这会让您创建一个获取和插入的事务。如何对可观察对象进行推理?
可观测数据处理数据流。流几乎可以是任何东西,但您可以将其视为异步事件的抽象数组。这很有用,因为您现在可以更清楚地对它们进行推理:
- 抽象因为Observable可以生成任何类型的值:
字符串、布尔值、对象
- 数组因为Observable的工作原理与JavaScript的数组方法类似:
map()、filter()、reduce()
- 的,因为Observable是值的包装
- 异步,因为可观察可能执行,也可能不执行
- 事件因为需要触发可观察事件
[“(创建主题)”,“选择主题”,“显示消息”]
消息是抽象数组,选择和创建是异步事件
如何使用可观察的?
正如我上面所说,让我们从结尾开始-“显示消息”
你可以在这里使用任何你需要的东西……这就引出了关于可观测的下一件大事:
“热”和“冷”观测值
默认情况下,可观察对象是冷的。这意味着当您创建一个可观察对象时,您只需描述它应该做什么。它不会立即执行这些操作(如Promises
do),它需要被触发
您可以通过订阅来触发它,可以手动使用subscribe()
方法,也可以让Angular使用async
管道(为您订阅)使其变得热
关注变化
下一步要做的事情(或者上一步,因为我们在计划中正在后退)是“选择主题”
。最好观察所选主题的值,并通过加载新消息来响应它的更改。这可以通过
Subject是一种桥梁或代理,在ReactiveX的某些实现中可用,既作为观察者又作为可观察对象。因为它是观察者,所以它可以订阅一个或多个可观察对象,因为它是可观察对象,所以它可以通过重新发送来通过它观察到的项目,还可以发出新的项目
我们可以设置主题$
,这样做:
class ListComponent {
public messages;
public topic$ = new Subject();
constructor(private http: Http) {
this.getMessages('posts');
this.topic$
.subscribe(topic => this.getMessages(topic));
}
getMessages(topic: string) {....}
selectTopic(topic: string) {
this.topic$.next(topic)
}
}
收尾
最后一步是在主题不存在时执行“(创建主题)”
。假设主题不存在时服务器将返回错误:
getMessages(topic: string) {
this.http.get(API_URL + topic)
.map(response => response.json())
.subscribe(
messages => this.messages = messages,
error => this.createTopic(topic)
);
}
createTopic(topic: string) {
this.http.post(API_URL + topic, { body: JSON.stringify(topic) })
.map(response => response.json())
.subscribe();
}
下面是这个示例的示例。正如您所看到的,这并不难做到(50行代码…)。您可以轻松地在需要的地方移动东西并创建服务。事实上,反应式编程允许创建异步数据流。这意味着您可以利用
Angular2的HTTP支持利用操作符(flatMap,…)将流链接在一起并实现复杂的处理链。这意味着您可以使用反应式编程/RxJS的所有概念将HTTP请求作为异步数据流的一部分
下面是一个简单的示例,它允许根据表单输入的值执行请求(当发生更新时):
操作员还可以在HTTP上下文中轻松实现几个问题:
- 确保在按顺序执行请求时收到最新的请求(例如基于用户输入)。触发新请求时取消先前进行中请求的
开关映射
运算符示例
this.ctrl.valueChanges.switchMap(
val => {
return this.http.get(`http://...?filter=${val}`);
});
- 缓冲事件,并在一段时间后触发最后一个事件
getMessages(topic) {
this.http.get("/messages?topic=" + topic)
.map(response => response.json())
// chain other operators here...
.filter(message => !message.private)
}
getMessages(topic) {
this.http.get("/messages?topic=" + topic)
.map(response => response.json())
.subscribe(messages => this.messages = messages);
}
class ListComponent {
public messages;
public topic$ = new Subject();
constructor(private http: Http) {
this.getMessages('posts');
this.topic$
.subscribe(topic => this.getMessages(topic));
}
getMessages(topic: string) {....}
selectTopic(topic: string) {
this.topic$.next(topic)
}
}
getMessages(topic: string) {
this.http.get(API_URL + topic)
.map(response => response.json())
.subscribe(
messages => this.messages = messages,
error => this.createTopic(topic)
);
}
createTopic(topic: string) {
this.http.post(API_URL + topic, { body: JSON.stringify(topic) })
.map(response => response.json())
.subscribe();
}
this.inputControl.valueChanges.debounceTime(500).flatMap(
val => {
// Execute ab
return this.http.get(`http://...?filter=${val}`);
}).subscribe((data) => {
this.places = data;
});
this.ctrl.valueChanges.switchMap(
val => {
return this.http.get(`http://...?filter=${val}`);
});
this.ctrl.valueChanges.debounceTime(500).flatMap(
val => {
return this.http.get(`http://...?filter=${val}`);
});
var params = new URLSearchParams();
params.set('placename_startsWith', searchText);
params.set('username', 'XXX');
return this.http.get('http://api.geonames.org/postalCodeSearchJSON',
{ search: params })
.retryWhen(error => error.delay(500))
.timeout(2000, return new Error('delay exceeded'))
.map(res => res.json().postalCodes);