HTTP driver
Hello World 和 计数器 这两个例子帮助我们认识到了如何在 Cycle.js 中建立 DOM 相关的流,如何和 DOM 相关的副作用打交道。实际业务中,前端作为呈现后端数据的一个载体,还需要和后端相关的副作用沟通,比如我们的 HTTP 请求及响应。Cycle.js 也为我们提供了 HTTP driver 来操纵 HTTP 副作用,我们首先在前端引入:
<script src="https://rawgit.com/cyclejs/cycle-http-driver/v7.0.0/dist/cycle-http-driver.min.js"></script>
我们设计一个小应用,单击页面上的 Get User
按钮,将通过 GET 方法请求 http://jsonplaceholder.typicode.com/users/1
上的用户数据,并显示在下方的内容区域中:
仍然考虑需求中存在的流和副作用:
- DOM 读取副作用:
Get User
按钮的单击事件流 - HTTP 读取副作用:对
http://jsonplaceholder.typicode.com/users/1
的请求流 - HTTP 写入副作用:对
http://jsonplaceholder.typicode.com/users/1
的响应流 - DOM 写入副作用:在内容区域显示数据的显示流
下面使用 Cycle.js 完成这个应用:
const { div, button, h1, h4, a, makeDOMDriver } = CycleDOM;
const { makeHTTPDriver } = CycleHTTPDriver;
function main(sources) {
const url = 'http://jsonplaceholder.typicode.com/users/1';
const click$ = sources.DOM.select('.get-user').events('click');
const request$ = click$.map(evt => ({
url,
method: 'GET'
}));
const response$$ = sources.HTTP
.filter(response$ => response$.request.url === url);
const response$ = response$$.switch();
const user$ = response$.map(response => response.body).startWith(null);
return {
DOM: user$.map(user => {
return user === null ? div([button('.get-user', 'Get User')]) :
div([
button('.get-user', 'Get User'),
h1(`${user.name}`),
h4(`${user.email}`),
a({ href: user.website }, `${user.website}`)
])
}),
HTTP: request$
};
}
const drivers = {
DOM: makeDOMDriver('#app'),
HTTP: makeHTTPDriver()
};
Cycle.run(main, drivers);
response$$
中的双美元符号 $$
表示这个流是一个嵌套流,其 emit 出的值仍是一个 Observable,一般需要对这样的流进行 展开 -- switch()
。