在RxJS中基于异步加载的DOM创建流

时间:2014-11-21 11:08:06

标签: javascript rxjs

我通过ajax调用加载一组项目 - 这是我的初始DOM:

<section class="books">
</section>

通过AJAX调用,我从服务器加载一些书籍,以JSON形式返回,以创建以下DOM结构:

<section class="books">
  <section class="book">
    ..
  </section>
  <section class"book">
  ..
  </section>
  # and so on
</section>

这是我执行AJAX调用的方式:

buttonClickStream = Rx.Observable.fromEvent queryButton, 'click'

requestStream = buttonClickStream
  .map ->
    bookName = $('#query').val()
    "/books/list?book=#{bookName}"

responseStream = requestStream
  .flatMap (requestUrl) ->
    disableForm()
    Rx.Observable.fromPromise $.getJSON(requestUrl)

通过订阅responseStream(并将JSON响应转换为HTML),我将其添加到DOM中,如下所示:

booksHTMLStream = responseStream
  .map (json) ->
    _.map(json.books, (book) -> bookTemplate(book))

bookHTMLStream.subscribe(
  (html) ->
    booksContainer.html(html)
)

现在,我要做的是附加一个用于点击<section class="book">元素的流,这些元素已在booksHTMLStream的第一个值返回中添加到DOM中。我知道我可以在<{1}}区块中添加内部,但这让我想起了回调 - 汤 - 我觉得我做错了。

我最初无法添加蒸汽,因为页面加载时没有subscribe元素,因此流永远不会触发任何值。所以,我想知道的是,是否有可能异步地将流添加到流中,或者是否有任何好的方法来实现我想要的东西而不会变成混乱的回调情况?

干杯:-)

2 个答案:

答案 0 :(得分:3)

bookClickStream = booksHTMLStream
  .take 1
  .flatMap (bookElements) ->
    Rx.Observable.fromArray bookElements
  .flatMap (bookElement) ->
    Rx.Observable.fromEvent bookElement, 'click'

没有测试过这段代码,但这大概就是这个想法。

答案 1 :(得分:0)

我通过为整个文档制作点击流,然后根据event.target进行过滤来解决这个问题。

clickStream = Rx.Observable.fromEvent document, 'click'

queryStream = clickStream
  .filter (event) ->
    $(event.target).attr('id') == 'query-button'

bookClickStream = clickStream
  .filter (event) ->
    $(event.target).hasClass('book') || $(event.target).parents('.book').length > 0

可能有更好的解决方案,我很乐意听到: - )