import Cycle from '@cycle/core' import { makeDOMDriver, hJSX } from '@cycle/dom' import { makeHTTPDriver } from '@cycle/http' const GITHUB_SEARCH_URL = 'https://api.github.com/search/repositories?q=' function main(responses$) { const search$ = responses$.DOM.select('input[type="button"]') .events('click') .map(_ => { return { url: GITHUB_SEARCH_URL } }) const text$ = responses$.DOM.select('input[type="text"]') .events('input') .map(e => { return { keyword: e.target.value } }) const http$ = search$.withLatestFrom(text$, (search, text)=> search.url + text.keyword) .map(state => { return { url: state, method: 'GET' } }) const dom$ = responses$.HTTP .filter(res$ => res$.request.url && res$.request.url.startsWith(GITHUB_SEARCH_URL)) .mergeAll() .map(res => JSON.parse(res.text)) .startWith({ loading: true }) .map(JSON => { return <div> <input type="text"/> <input type="button" value="search"/> <br/> <span> {JSON.loading ? 'Loading...' : `total: ${JSON.total_count}`} </span> <ol> { JSON.items && JSON.items.map(repo => <div> <span>repo.full_name</span> <a href=https://www.jb51.net/article/{ repo.html_url }>{ repo.html_url }</a> </div> ) } </ol> </div> } ) return { DOM: dom$, HTTP: http$, } } const driver = { DOM: makeDOMDriver('#container'), HTTP: makeHTTPDriver(), } Cycle.run(main, driver)
有了实例1做铺垫,这段代码也就通俗易懂了,需要提示的是:
Rx的Observable对象,命名上约定以$符为结束,以示区分
Observable.prototype.withLatestFrom()的作用是:在当前Observable对象的事件触发时(不同于 combineLatest),去合并参数的目标Observable对象的最新状态,并传递给下一级Observer
以上项目完整实例,可在 /rockdragon/rx_practise/tree/master/src/web 找到
小结
寥寥数语,并不足以概括Cycle.js,比如 MVI设计模式,Driver的编写,awesome-cycle 这些进阶项,还是留给看官们自行探索吧。