David Tuite
David Tuite

Reputation: 22663

How to structure an application for creating items into a list with Backbone.Marionette?

This in one of the thing that still confuses me using Marionette.

Imagine a simple interface for viewing a list of comments and making a new comment. The way I'm structuring this currently is with a CommentApp like I have included below.

I guess there are two parts to my question:

Is this how I should be structuring this type of application? I tried to follow the BBCloneMail Example App where possible but that doesn't seem to provide an example of creating new items into a collection.

Why is the layout.listRegion below returning undefined where I try call .show() on it? More generally, is there a definitive way to handle triggering and binding to 'layout:rendered' events with nested layouts. It seems like it gets rather confusing.

App.module "CommentApp", (CommentApp, App, B, M, $, _) ->
  class Layout extends M.Layout
    template: 'comment_layout'

    regions:
      listRegion: '#comment_list_region'
      newRegion: '#new_comment_region'

  class CommentView extends M.ItemView
    # this is as you would expect

  class NewCommentView extends M.ItemView
    # this is as you would expect
    # This view triggers a 'new:comment' on the CommentApp.vent
    # event aggregator when the user submits a new comment.

  class CommentsListView extends M.CollectionView
    # this is as you would expect
    # This view listens to the 'new:comment' event on the
    # CommentApp.vent event aggregator.

  # Public API
  # ----------

  CommentApp.showComments = (comments) ->
    # In here I need to render a layout
    layout = new Layout()

    # I also need to render a comments list an the
    # view for writing a new comment.
    commentsListView = new CommentsList(collection: comments)
    newCommentView = new NewCommentView()

    # THen I need to place these views into the layout when ready.
    layout.on "show", ->
      # This part fails because it seems that the layout.listRegion
      # is not yet defined for some reason. Don't understand why?
      layout.listRegion.show(commentsListView)
      layout.newRegion.show(newCommentView)

    # Now I need to stick the commenting layout into it's
    # place in the main app layout.
    App.layout.mainRegion.show(layout)


  App.addInitializer (options) ->
    @vent.bind "layout:rendered", -> CommentApp.showComments(comments)

The 'comment_layout' template is just a basic container template:

<h2>Comments</h2>
<section id="comment_list_region"></section>
<section id="new_comment_region"></section>

And I'm using JST to render it. I've overridden the rendering function with this code:

# Override the marionette renderer to make it use JST.
Backbone.Marionette.Renderer.render = (template, data) ->
  # Check if a template is specified first.
  if template
    throw "Template '" + template + "' not found!" unless JST[template]
    JST[template](data)

Upvotes: 0

Views: 420

Answers (1)

Derick Bailey
Derick Bailey

Reputation: 72878

Structure

Your app is generally structured the way I would do it. There's a couple of points I would change, though.

For example, you don't need to to use an initializer to set up the event binding for "layout:rendered". You could do this instead:

App.vent.bind "layout:rendered", -> CommentApp.showComments(comments)

There isn't any real value in setting up the event binding inside of the initializer in this case.

Layout

Why is the layout.listRegion below returning undefined where I try call .show() on it?

... that one I'm not sure about... though this code looks a bit odd: App.layout.mainRegion.show(layout)

was this intended to be App.mainRegion.show(layout) ?

A layout's regions will be instantiated when the layout's render method is called. Showing a layout in a region will call the layout's render method, and listening to the show event of the layout in order to display stuff in the layout's regions should work fine. In fact, I do this quite regularly.

I've seen several reports of issues similar to this recently, though, and I'm thinking there's a bug in here somewhere that I just haven't been able to isolate.

What is the template comment_template referring to? Is this a precompiled template somewhere? Have you overridden the rendering of templates? If so, can you post the code that handles this?

If you do a console.dir(layout) inside of the layout's "show" event handler, what does it come back with? Do you see the region objects? What else do you see on that object?

Upvotes: 2

Related Questions