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.
Related
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 using backbone with underscore. I have a button
<%= model.testButtonText %>
This button is rendered in the render function of my view using template.
I am wondering if there is a way to automatically update the button's text when the model.testButtonText changes?
Or do I have to handle it specifically by binding to the model.testButtonText change and then do some jquery to find the element and update the text that way.
If you don't want to bind every element to model change event you can use this plugin: http://rivetsjs.com
Natively Backbone doesn't support ui-bindings.
Since it's tied to the model itself, you can listen for changes in your view to re-render it.
view.listenTo(this.model, 'change', this.render);
A useful extension for re-creating the view when your model changes -- Backbone.ModelBinder.
I use backbone.js and have a model without a collection.
In the view I call fetch on the model with a callback to render the view.
this.user.fetch({success: function(d) { self.randomUserView.render() }})
how can I make the view update automatically when the model change? e.g. I don't want to specify the above callback every time I call fetch. I tried to bind the view to many model events on initialize but this did not work.
On the view, add an event handler to the view's model:
initialize: function() {
this.model.on('change',this.render,this);
}
Backbone is event-driven, not callback driven framework (although technically they are callbacks). And your approach does not seem to be native to Backbone. When you do fetch(), user model will automatically trigger "add" event. All you need to do is in the corresponding view add this in initialize:
initialize: function() {
... your code...
this.model.bind('add', this.render);
}
This way you subscribe to this even only once in the view init and don't have to ever pass explicit callbacks.
Actually if you want to have a view refresh on fetch on a collection you need to bind RESET!
this.model.bind('reset', this.render, this);
Update is only fired if the current collection is edited.
ps bindAll is dangerous and lazy. (and probably going to cause you problems down the line)
I have a div with id #content in which I render a view (view.el: "#content") with a model.
In this view I have an event ("click #save": "save").
When I override the view (= I render the same view on a new model, for example) the save event fires twice.
This happens because the this.undelegateEvents(); method unbinds events using the cid and every new view has a different cid.
How can I fix it?
Before you instantiate a new view, you will need to call undelegateEvents on the old view.
I don't understand why should I bind on render inside view Initialize?
example:
_bindAll(this, "render") ??
You do not have to, but if your render is triggered based on an event, you will want it to run within the context of your view (this). If you have something like this:
this.model.bind("change", this.render)
The change event will be run within the context of the model, but you want the render call to run against the view.
To simplify all this binding, you can use _.bindAll and list all the methods you might call from outside your views. You should know that Backbone is auto binding the callbacks used for UI events:
events: {"click" : "render"}