Creating a stream based on an asynchronously loaded DOM in RxJS

I load a set of elements through an ajax call - this is my internal DOM:

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

With an AJAX call, I download some books from my server returned as JSON to create the following DOM structure:

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

This is how I make an AJAX call:

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)

And by subscribing to responseStream(and converting the JSON response to HTML), I add it to the DOM, for example:

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

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

Now, what I want to do is attach a stream for clicks on elements <section class="book">that were added to the DOM in the first return value from booksHTMLStream. I know that I can add this block insidesubscribe , but it reminds me of a callback soup - and I feel like I'm doing it wrong.

, <section class="book">, . , , - , , ?

:-)

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

, .

+3

, , 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

, : -)

0

All Articles