I see that both share almost the same properties & functions so what is the main difference for these two?
That question is addressed here: https://github.com/marionettejs/backbone.marionette/wiki/Use-cases-for-the-different-views
In short, you'll want to use CompositeView if you want to wrap a template around the collection (ex: a list with a header and footer). CollectionView doesn't know how to render a template.
http://blog.marionettejs.com/2016/08/23/marionette-v3/index.html
Version 2.x had many different kinds of views: View, ItemView,
LayoutView, CollectionView, CompositeView.
In version 3 ItemView, and LayoutView were ‘merged’ into View, and
CompositeView was deprecated for removal in v4. Now we have only View
and CollectionView.
and layouts were removed too
Related
I've been studying this Backbone tutorial and came across this bit of code:
var LibraryView = Backbone.View.extend({
el:$("#books"),
initialize:function(){
this.collection = new Library(books);
this.render();
},
...
});
The author explains that this.render() makes the view render when its constructor is called.
When would you not want the view to self-render?
The render method does nothing more than adding HTML to the DOM by using jquery's html or append methods. Where you choose to call the render method on the view is an architectural choice.
Backbone is said to apply the MV* pattern where models are bound directly to the view.
As such, the view would render itself upon instantiation, and have the ability to render itself when the model changes.
However, Backbone leave a lot of decisions to the developer and is a flexible library. There is nothing that technically prevents you to use control objects that manage the flow of the views; as such, another object can instantiate and re-render the view as well.
var view = new Bb_View();
view.render();
In the end, render is just a method on the view, and you can define your own methods as well. An example reason why I would call custom methods on the view from outside the view, is when I keep reference to an array of views.
As an event occurs, I loop through the views, I might add some conditions, and then call the custom method on particular views based on the condition.
I have multiple templates declared in my Marionette ItemView and when I render my ItemView I say which template I want to use.
templates: {
'images': ImageResultTmpl,
'music': MediaResultTmpl,
'videos': MediaResultTmpl
},
Inside a method in the ItemView can get the name of the active template?
if(music){
do this;
}
else{
do that;
}
My first thought is that you should just have different ItemViews for each template and render the correct ItemView depending on the situation. If you're trying to DRY up your code, maybe create a base ItemView that holds the common code and then have specialized ItemViews that extend that base class.
I construct a CompositeView by passing it a collection. The collection gets its data via a url. I'm using the defer/promise technique to wait till the collection is populated before constructing the View.
Later I call fetch on the collection again, modifying the url.
To my surprise the CompositeView is re-rendered with the new data in the Collection. I thought I would have to do something e.g.:
collectionEvents: {
"sync" : "render"
}
But I'm not doing anything. No event binding at all. I thought in marionette I would have to handle this 'manually'.
This looks like something to do with CollectionView: Automatic Rendering. Does this happen with models and item views as well? And why do some tutorials etc. explain about binding?
Thanks
--Justin Wyllie
Yes but the only thing that will be re-rendered will be the collection, if you are using a CompositeView to display a model and a collection, the model part will not be re-rendered, you have to set an event for that.
So the CompositeView has the same behavior of the collectionView and it will re-render the collection whenever theres a change in the data.
And to your second question this does not happens in the ItemViews when the model changes.
this you have to do it on your own when its best for you application needs.
I'm working my way through my first attempt at using Backbone.Marionette and wondered if there is any reason to use a Backbone.Marionette.ItemView when a simple Backbone.View will suffice?
Thanks!
Marionette's ItemView provides a default render and close method which do a few things for you.
render does the following (amongst other things):
1) Marks view as !this.isClosed (related to showing views in Regions, another Marionette concept)
2) Triggers before and after render events
3) Calls a serializeData method to get data (defaults to data from either this.model or this.collection.
4) Gets the template (possibly from TemplateCache) and renders via Marionetter.Renderer
5) Binds UI elements
In addition to this "free" render method, you also get close functionality.
Of course, if you are using a CollectionView/ItemView combination (which is very powerful) or a CompositeView/ItemView, you HAVE to use an ItemView.
Outside of those cases, one big benefit is that you KNOW your view is going to be compatible with Marionette Regions. Ideally, in a Marionette app, you use separate regions to show your views, like so:
var myView = new MyView();
// render and display the view
MyApp.mainRegion.show(myView);
// closes the current view
MyApp.mainRegion.close();
If MyView is a Marionette ItemView, this will work like a charm. If it is just a raw Backbone View, you will probably need to do some work to make sure that it works as planned.
In my apps, I typically just opt for using ItemView as the basis for all of my non-Collection and non-Composite Views.
I am developing a Backbonejs app using the excellent Marionette plugin.
I have a big navigation view consisting of <a> tags referencing various collections. An example will better explain this:
Cars
Car A
...
Car Z
Books
Book A
...
Book Z
Each block is a collection of models. Eg. CarList, BookList
How do i best architect the Menuview so that, whenever any of the model changes in any of the collection the Menu view is rerendered?
Maybe you could try to use a Composite View for your menu view and a Collection View for every sub-folder of your menu. Composite and Collection Views are made in a way that they will add/remove automatically a child element when a model is added/remove to the collection.
For more information you can check here: http://lostechies.com/derickbailey/2012/04/05/composite-views-tree-structures-tables-and-more/