3

we are using Backbone,Marionette and handlebars for my application. When I try to render my view inside Marionette.Region, one extra div wrapping around the template. How can I avoid this.

html code :

 <div id="mainDiv"></div>
   <script type="text/x-handlebars-template" id="basic">
        <div id="first"></div>
        <div id="second"></div>
    </script>

js code :

 //function
var templateCompilation=function(templateId,data){
   var alertCompilation=Handlebars.compile(document.getElementById(templateId).innerHTML);
   return alertCompilation(data);
};

//Application
myApp = new Backbone.Marionette.Application();
myApp.addRegions({
 mainContainer:"#mainDiv"
});
myApp.start();

//first view
var basicView=Marionette.ItemView.extend({
  template:function(){
     return templateCompilation("basic",{});
  }
});

//reding view
var basicViewObj=new basicView();
myApp.mainContainer.show(basicViewObj);

To avoid extra div, I try with following statements my bad luck nothing working.

var basicViewObj=new basicView({el:$("#mainDiv")});
var basicViewObj=new basicView({tagName:""});

can anyone help me.

seebiscuit
  • 4,905
  • 5
  • 31
  • 47
ur truly friend
  • 553
  • 4
  • 11
  • 23
  • 2
    possible duplicate of [Backbone js: How to remove extra tag in view?](http://stackoverflow.com/questions/7663895/backbone-js-how-to-remove-extra-tag-in-view) – Evgeniy Dec 11 '14 at 07:28
  • @Evgeniy In my question, I want to refer both `Region` and `view` to the same element. If I am using only `views`, whatever you posted it will help but my question was different. I am using both `Region` and `Views`. I hope you might understand. – ur truly friend Dec 11 '14 at 07:40
  • possible duplicate of http://stackoverflow.com/questions/11183130/extra-divs-in-itemviews-and-layouts-in-backbone-marionette and http://stackoverflow.com/questions/11195242/extra-wrappers-in-backbone-and-marionette – Deeptechtons Dec 11 '14 at 09:52

1 Answers1

1

Important Update:

The code below the line will not work. I wrote it without testing it (was on my mobile). The following update has been tested and incorporated the important comment suggested by @vzwick.

As explained below, override attachHtml in the Region. We are going to three important changes to attachHtml as annotated in the comments below

myApp.mainContainer.attachHtml = function (view) {
    // empty the node and append new view
    this.el.innerHTML="";

    // All view elements are attached to that view's el, which acts as a
    // container for that view. The OP wants to get rid of that container 
    // and use the region's el instead. So first get the children of the
    // view that we want to show in the Region
    var children = view.el.childNodes;

    // Now pop each child element into the el of the Region
    // Note that Node.appendChild(Node) removes the first element from the 
    // Node array on each iteration so children[0] will be the next
    // child for each iteration
    while (children.length > 0) {
        this.el.appendChild(children[0]);
    }
     
    // Finally, assign a new el to the view:       
    // view.setElement(element, delegate) is a Backbone method
    // that reassigns the el of the *view* to the parameter *element*
    // and if delegate = true, re attaches the events to the new el
    view.setElement(this.el, true)
}

The important thing to note is that the OP's basicView now shares its el with myApp.mainContainer. Since myApp.mainContainer is a Region and it does not take an event parameter there isn't a chance of there being conflicts if events are re-delegated. The same is true if this is used with a LayoutView since the re-delegation of events would happen to the LayoutView Region el, and not the LayoutView el, then there should be no conflicts.


Beginning of old post

I haven't tried this before, but I'm sensitive to your problem from a functional and structural level. What I suggest you do is override the Region's attachHtml function.

By default Backbone.Marionette's attachHtml is doing this

attachHtml: function(view) {
    // empty the node and append new view
    this.el.innerHTML="";
    this.el.appendChild(view.el);
}

To change this functionality you could define a new attachHtml in your Region like the following:

attachHtml: function(view) {
    // empty the node and append new view
    this.el.innerHTML="";
    this.el.appendChild(view.el.childNodes);
}

Now the Region el will directly append the inner nodes of the view that you're showing in that region.

To override the original attachHtml of the mainContainer region you would use your Application variable, i.e.

myApp.mainContainer.attachHtml = function (view) { ... }

with the code example written above.

Community
  • 1
  • 1
seebiscuit
  • 4,905
  • 5
  • 31
  • 47
  • 2
    This is most likely (cannot verify since I'm on mobile right now) terrible advice since Backbone's View event bindings from the `events` hash are scoped to the view's `el`. Hence, while your hack would have the DOM nodes attached without a container, Backbone's DOM event model would get broken beyond repair. – vzwick Dec 14 '14 at 21:01
  • Excellent point @vzwick. I have not tested this either, but I wonder if using `this.setElement = MyApp.mainContainer` in the view being `show`n in the `mainContainer` `Region` would fix the problem you bring up. Of course, this would imply that all Backbone events for the `mainContainer` `Region` would have to be wired either on the `Region` or the `View`, since whenever `delegateElements` is called, the first thing it does is `this.undelegateElements()`, and would lead to a lot of confusion about what events are actually wired. But that's what the OP required in the question. – seebiscuit Dec 14 '14 at 21:09