Closed abritinthebay closed 10 years ago
Any update on this? I've been using your plugin and now find myself needing to render subviews dynamically when the fetch data arrives.
I ended up going with the bossview+collectionview solution I mentioned above which was actually pretty clean after a little bit of a refactor.
That said - this would still be extremely useful feature for other issues.
Hmm, in my case i have three views, on i prefetch before i add to regions. The other two i have to figure out a way to render the view IF the data comes through and there are no 500s. Any suggestions?
Well given that the views can be independent of the model - maybe just work event based?
Like... have the view check if there is data in the model or if it sync'd and then do a remove/hide if it errors out? Or just have it hidden until you know it synced?
The subview code can be refactored in this case so I may end up just submitting a pull request to add InsertSubView as a method
Just to give you an idea, this is how i was fetching from two apis:
$.when(billingModel.fetch(), membershipModel.fetch()).done(function () {
model = new Model({ billing: billingModel, membership: membershipModel });
view = new View({ model: model });
Core.addRegions({ mainRegion: Core.el });
Core.mainRegion.show(view);
}).fail(function(){
console.log('either billingModel or memberShipModel did not fetch correctly!');
});
The problem is, sometimes the billingModel will fail with 503 or similar but I still need to render the membershipModel which will always work. Here is how the master (boss) view look like:
var View = Marionette.BossView.extend({
subViews: {
heading: HeadingView,
membership: MembershipView,
balance: BalanceView,
personal: PersonalView
}
});
of the views above, i would like to not render "membership" and "personal" if the billingModel fetch fails with 503 or similar.
Sounds like an event driven solution would be best for you for sure. Hell... you could ONLY render the membership and personal on success then.
So you just need a backbone event emitter, and that could be the parent view - or whatever works for your system.
Then when the billingModel is rendered it just triggers an event on that emitter and the subviews then render automatically on that event. Until then they simply don't render.
This would require overriding the render function on those views, but it's a pretty trivial function at that point.
That sounds exactly like the solution that I need but how do i add new views to bossview in the future and also, how do i specify the order?
Well in the case I'm talking about - you just add them as normal and let the views themselves dictate what happens. They can call this.remove() if they aren't needed anymore.
But yes - this feature needs to be added.
Gotcha! Thanks for the clarification. Okay, for reference:
var OptionalView = Marionette.ItemView.extend({
template: _.template(''),
initialize: function () {
var that = this;
this.model = new MyModel();
this.model.fetch()
.done(function() {
that.template = _.template('NEW TEMPLATE <%= boo %>'),
that.render();
})
.fail(function() {
that.remove();
});
}
});
I was thinking more a case of
this.listenTo(model, "sync", successCallback);
this.listenTo(model, "error", failCallback);
as I'm not sure about how promises/deferreds are handled in Backbone. Also it's a cleaner read.
I pushed to a branch called insertsubview. Please try my updated Marionette.BossView.js: https://raw.githubusercontent.com/justspamjustin/BossView/insertsubview/Marionette.BossView.js
Bossview now has two new functions:
initializeSubView(subViewName, subViewFunction)
The subViewName
is the equivalent of what would be the name of the key in your subViews
object. And subViewFunction
is the equivalent of what would be the value in your subViews
object.
There is also:
renderSubView(subViewName)
pass the name of the subView to render at any time in the views lifecycle. Try it out and let me know. If it works for you, I'll merge it into master.
This seems to work great. Would love you to merge this in :) :+1:
Merged in and is v0.1.4.
Haha, great work for this :-)
Right now I'm reduced to the following for dynamic updating
This is obviously a bit rough.
A simple insertView/addSubView method could takethe view (or object for a list of views) and then do the needed setup.
Would create much cleaner code when dealing with dynamic subviews (that may not be directly from a collection for example).
Sure I could make a contrived collection and use some form of CollectionView but then I end up writing a whole lot of other boilerplate code that doesn't really solve the issue and I end up not at an ideal solution anyhow :(