-->

Backbone, Bootstrap modal within template not show

2019-04-12 23:36发布

问题:

I am trying to generate a modal for each of my posts so that each post has a modal containing the post content(and eventually comments). When the comment link is clicked the modal will appear. The thing is I have to create a bootstrap modal block for each post so i decided it would be easiest to do this in my backbone template. Why isn't this working?

Here is my code:

app/assets/templates/posts/index.jst.eco

<% for post in @posts.models: %>
<tbody><td>
<%= post.get('content') %>
</td></tbody>
<tr><td>
<a href="#<%= post.get('id') %>">Comment</a>
</td></tr>
<div class="modal" id="post-<%= post.get('id')%>" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-header">
<%= post.get('content') %>
</div>
</div>
<% end %>

app/assets/javascripts/routers/posts_router.js.coffee

class Voice.Routers.Posts extends Backbone.Router
        routes:
                '': 'index'
                ':id': 'show'
        initialize: ->
                @collection = new Voice.Collections.Posts()
                @collection.fetch()
        index: ->
                view = new Voice.Views.PostsIndex(collection: @collection)
                $('#container').html(view.render().el)
        show: (id) ->
                $("#post-#{id}").modal('show')

There are no errors in the js console, the modals just don't seem to appear. each post has a modal block with an html id field equal to "post-(the posts id)"

Any help is much appreciated!

回答1:

This sounds very similar to a lot of SO questions on Bootstrap modals and using Backbone. Checkout this solution from Dereck Bailey,

http://lostechies.com/derickbailey/2012/04/17/managing-a-modal-dialog-with-backbone-and-marionette/

// the template
<script id="modal-view-template" type="text/html">
  <div class="modal-header">
    <h2>This is a modal!</h2>
  </div>
  <div class="modal-body">
    <p>With some content in it!</p>
  </div>
  <div class="modal-footer">
    <button class="btn">cancel</button>
    <button class="btn-default">Ok</button>
  </div>
</script>

// the html has only one modal div
<div id="modal"></div>


// inside your show router function
var view = new MyView();
view.render();

var $modalEl = $("#modal");

$modalEl.html(view.el);
$modalEl.modal();

His explanation is,

The core of the problem that people run in to when using a modal dialog is that the modal plugin removes the DOM element that wraps the modal, from the DOM. It usually gets added to some special holding location where the modal plugin can guarantee that the element won’t be visible until the modal dialog is opened. I’m over-generalizing this a bit, but many of the modal dialogs work this way or in a similar manner.

The problem that this usually causes is that a Backbone view will lose it’s event handling when the DOM element gets moved around by the modal dialog. When the modal dialog removes the view’s el from the DOM, the events configuration is lost because the DOM element has been moved or removed from the DOM and jQuery had to let go of the events. When the el is re-added to the DOM for displaying it as a modal, then, the events are not re-attached.