Search code examples
javascriptbackbone.js

InnerView not responding to DOM events in its template


Question: when I create the Backbone view inside the scope of another view, the inner view is not responding to DOM events that originate inside its template, however, the outer view is responding to those events. In the example below, the innerview has a submit button, but only the outerview will respond to the click of the submitButton

I'm making a Backbone project that creates a new main view for each route in the Router, and that main view might have subviews for different parts of its page. For example, there's a an order route that creates the OrderView page

routes: {

            'order': 'orderProduct'
        },

orderProduct: function(){

            this.loadView(new OrderView()); 

        },

In the initialize function of OrderView, I create subviews for the OrderView, for example, a formView.

 var OrderView = Backbone.View.extend({


        initialize: function(){
            $("body").html(this.el);
            this.template = _.template($('#order-template').html()),

            this.subViews = [];
            var formView = new FormView();
            this.subViews.push(formView);
            this.render();
        }, 

Then in the FormView, I create the obvious, such as a submitButton

 var FormView = Backbone.View.extend({
        el: '#forForm',

        initialize: function(){
            this.template = _.template($('#form-template').html());
        },
        events: {
            'click #submitButton' : 'submitForm',
            },

        submitForm: function(){
            ...
        },

        render: function(){

            $('#forForm').append(this.template());
            return this;

        } 
     });

The form is rendered to the page, but when I click submit nothing happens. I then added event handler and corresponding function 'click #submitButton' : 'submitForm', to the OrderView and it responded to the submit event. So my question is, when I create the FormView inside the scope of the OrderView, why can't the FormView respond to events inside the scope of its template?

FormTemplate

   <script type="text/template" id="form-template">
    <button id="submitButton">submit</button>
   </script>

Update:

I should note that the dom element where the form-template (rendered by the inner view) is appended is contained in the order-template (the outer view). Even though that's the case, since the events the FormView is responding to originate in clicks inside the form-template (i.e. when submitButton is clicked), I assumed FormView would be able to respond to the events.

<script type="text/template" id="order-template">
  <div class="container">

    <div class='row'>

      <div class="col-md-6">



     <div id="forForm">
     </div>



      </div> 
      <div class="col-md-6">

     ...ommitted...

      </div> 

  </div>

  </div>

</script>

Solution

  • For some reason, I had to use setElement when rendering the FormView from the render function of the OrderView, setting the OrderView container to be the element of the FormView. I don't know why this is necessary. I've seen many Backbone apps that render one view inside another (for example, apps that use separate views for ul and each li in a list) and that's never seemed necessary

    This is the relevant code from the render function of the OrderView

            _.each(this.subViews, function(view) {          
                view.setElement( this.$el.find('.orderview-container') ).render().el;           
            }, this);