Reputation: 4204
What is the best approach for switching views for a model?
I have a collection of models, and each model is represented by a view, say a jquery draggable div. When the divs are dragged to a certain area of the page, I would like to use a different view representation.
Should I: a) Set up different views for each model, and switch the views? Can I have different "el"s for each view, and switch which "el" is used? b) Build different DOM elements into a single view and show/hide accordingly?
Also, if I wanted to have a "hidden view", and rather than just use hide(), how can I detach all DOM elements associated to the model but still keep the model in the collection? I would also like to re-attach or re-render the DOM elements some point later.
Clarification: for the last paragraph above, what I meant was if I use hide() it just sets the visibility style to none, but if I had many hidden elements I am thinking it might be better to remove them from the page and re-render them when necessary. Let's say I had 100 of such elements that need to switch between 'hidden' and 'visible'. What do people think?
Upvotes: 3
Views: 1314
Reputation: 6790
I chose to render a new view and insert it above the old view just before removing the old view. It would be possible to cache the old view and restore it to the DOM (vs having to re-render it), but I didn't like this because the cached view consumes resources and continues responding to events in the app.
Alternately, you can create a container view as the placeholder for your view and swap the guts of it (the guts could itself be its own view) as you switch from one view to another.
Upvotes: 0
Reputation: 11334
I second @Jeremy. Let's think of it this way, if you didn't have backbone, but only jquery what would you do?? Probably create multiple divs (say) for the different type of views and toggle between them using jquery's toggle(...) function to toggle among them. Now you have backbone - what is different? Structural/cleaner organization of code. It doesn't directly influence your logic only organizes it better.
So what does this say: Have multiple views and bind them to the divs (for example) that you are going to use to view the model. Have a ViewHandler class that handles the different rendering of the views and does the toggling between them. Either use jquery's toggle (if the toggling is sequential) or create your own (very easy). Let ViewHandler's render function handle which view to call and which view to hide. The view object(s) continue to exist though it's only the corresponding DOM elements that are hidden.
You said:
Also, if I wanted to have a "hidden view", and rather than just use hide(), how can I detach all DOM elements associated to the model but still keep the model in the collection? I would also like to re-attach or re-render the DOM elements some point later
How are DOM elements associated to the model directly?? I mean the model is only meant to hold data. You can get the data from the elements but you shouldn't bind them to the DOM. That's the job of the view, so to speak. Model should ONLY contain data - if you are binding to a <p>
tag I'd rather you have property 'text' (of the Model) and bind to the innerHTMl/text of <p>
- All changes to the model should happen via the view only or the server's fetch etc., That way the model is only a data holder and you can keep them wherever you like for how long you like!! No need to reattach/detach views!
Once you hide the corresponding DOM element, it'll make the associated view inactive so you needn't worry about the attachment/detachment. If the underlying data (i.e., page data) changes, your models could update themselves when the view is visible :) I don't see how even having them bound to the DOM prevents you from manipulating the different objects?? They are 'bound' but not 'tied' to the DOM and the objects are just javascript objects/reference which you can store/move around. Unless you are actually storing jquery object references and unless you manipulate them outside the view substantially (nightmare!!) you should be fine just passing around the references too!
I'd still go with 'data' only approach for the models though and not have them bound to the view.
Does this clarify your confusion??
UPDATE: (as per clarification)
If you indeed had 100 odd elements and you wanted to hide/show them and are deciding whether delete/new-ing them would be a better option - I guess I'd still go with hide/show. Garbage collection in Javascript is best achieved by setting all object references to null. And then you create new ones again. It's possible to make a mistake and have memory leaks or dangling objects or objects with multiple references. If you know you are going to reuse the view soon enough on a show, I'd suggest hiding. If you are NEVER going to reuse it, setting it as null for garbage collection is the way to go, IMO.
Upvotes: 1
Reputation: 22415
The beauty of Backbone is that you can do it however you'd like. There's no right or wrong way, but there's probably a way that suits your application better.
My initial thought would be to have two separate views for the same model, but now that I think about it, you could just as easily have a toggle boolean in the view that lets the render function know which view to render in that specific case. This way you don't have to mess around with changing the el
.
Upvotes: 1