Devesh Kumar
Devesh Kumar

Reputation: 1019

Backbone Marionette : Add a model (and render its view) to a nested Composite View

If you don't want to see the complete code, here is what I am trying to do. I have multiple pages and each page has multiple tags. There is a composite View called PageManyView for rendering pages which called its childView PageView. Page View is a nested composite view which renders tags, passing this.model.get('tags') as collection.

Now I can easily add a new page by using pages.add(newPage). Here pages is the collection. I am facing problem in adding a new Tag. How can I do that. Please help.

CODE

var PageModel = Backbone.Model.extend({});

var PageCollection = Backbone.Collection.extend({
    model: PageModel
});

My JSON at /data endpoint is coming like this

[
  {
    _id: '1', 'name': '1', info: 'Page 1',
     tags: [{name:'main', color:'red'}, {name:'page', color:'blue'}]
  },
  {
    _id: '1', 'name': '2', info: 'Page 2',
     tags: [{name:'section', color:'blue'} {name:'about', color:'yellow'}]
  }
]

I have created Nested Views in Marionette like this:

TagView = Marionette.ItemView.extend({
   template: '#tagOneTemplate'
});

PageView = Marionette.CompositeView.extend({
    template: '#pagesTemplate',
    childViewContainer: 'div.tags',
    childView: EntityViews.TagView,
    initialize: function(){
        var tags = this.model.get('tags');
        this.collection = new Backbone.Collection(tags);
    }
});

PageManyView = Marionette.CompositeView.extend({
     template: '#pageManyTemplate',
     childView: EntityViews.PageView,
     childViewContainer: 'div#all-pages'
});

Now here is where i am facing problem. Inside Controller of my application, lets say if I have to add a new page

showPages: function(){
   //Getting pages by using jQuery deferred
    var view = PageMainView({collection:pages});
    view.on("add:page", function(){
       var newPage = Page({_id: 3});
       pages.add(newPage);
    });

}

Now this add function renders the new page automatically.

BUT I AM FACING PROBLEM IN ADDING a NEW TAG. HOW CAN I ADD A NEW TAG?

Upvotes: 2

Views: 1262

Answers (2)

Devesh Kumar
Devesh Kumar

Reputation: 1019

Finally it worked. Here is what I have done. Step 1: Get Current model (page) from pages collection.

var currentpage = pages.get(pageid);

Step 2: Use Marionette BabySitter to get the view of the page where I want to insert a new tag.

var v = view.children.findByModel(currentpage);

Step 3: Add tag to v.collection. Since v is the View of the page where I want to insert new tag, v.collection returns the initialised tags collection

v.collection.add(tag);

This works for me. Let me know if I am wrong somewhere or a better way exists. Hope it helps.

Upvotes: 3

samccone
samccone

Reputation: 10926

this can be done quite easily by shifting around how your collection is being passed in. Instead of setting the collection on initialize in your compositeView, you should pass it in directly during instantiation. This way when you make a change to the collection from within your model, the compositeView will hear the "add" event on collection and add node automagically for you

For example it might look something like this.

PageView = Marionette.CompositeView.extend({
    template: '#pagesTemplate',
    childViewContainer: 'div.tags',
    childView: EntityViews.TagView,
});

new PageView({
  model: myModel,
  collection: myModel.get("tags")
});

myModel.get("tags").add([{new: "object"}])

Upvotes: 0

Related Questions