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.
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 a CompositeView with a collection. The CompositeView has its own model and view that is pretty complex and changes made it to its childViews need to trigger the CompositeView's view to re render but not its childViews. Is that possible?
I read in the Marionette docs "You can specify a modelView to use for the model. If you don't
specify one, it will default to the Marionette.ItemView." But nothing happens when I try to use this in my CompositeView.
Your CompositeView should listen for change event of own model and should call render on that. In this way the only ItemView associated with the composite view will re-rendered on change of own model not all childView.
this.listenTo(this.model, 'change', this.render)
You can put this line inside initialize method of CompositeView.
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 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
In Backbone model views, it seems $(this.el).parent() doesn't work. What is the best way to select the parent element from within a view?
I am setting el by using tagName: "li" for the view.
By default, Backbone assigns an empty div to your view and you can't access its parent, until it's been placed in the DOM through your render function.
You can use your approach of $(this.el).parent() if you are allowing Backbone to assign the default empty div. You can use the this.el.parent() if you are assigning el yourself in the constructor to a jQuery object.
What are you setting this.el to? If you're already setting it to a jquery element, for example:
this.el = $('#content');
then you don't need to wrap it again. Try changing what you have to:
this.el.parent()