Reputation: 2217
I've been running into a few situations recently, where I have multiple views on the page that need to be backed by a single model. This way, just by modifying the model, all of the relevant views will automatically update their appearance. The problem is, in order to achieve this atm, I would need to write code that actively seeks out these models. I will occasionally get lucky and have a model provided to me through an event handler, but usually this isn't the case. I'm looking for a good way to have a single instance of a model on the page at a time, and then just references to that model everywhere else. How do people commonly handle this need? Backbone-relational handles it by keeping a central store using lawnchair.js, and I have heard of people using a single global collection to keep a registry of all of the models.
Upvotes: 3
Views: 1696
Reputation: 35750
Short Answer:
One model shared by multiple views (which you could call "duplicate models") is actually a perfectly valid (and useful) Backbone pattern; it's not a problem at all. From what I can tell the problem here is that it's difficult to get that model in to the multiple views, and therefore I'd suggest solving that instead.
Longer Answer:
The problem with passing a model to multiple views is that it inherently couples views together (in order to provide that shared model to each view, the parent view needs to also have that model, as do any "in between" views). Now as programmers we've been taught to keep things as encapsulated as possible, so coupling views might seem "wrong" at first. However, couple views is actually desirable: the key thing is to properly limit which views are coupled.
@Shauna suggested an excellent rule of thumb for this: "a view only cares about itself and creating its children." If you follow this rule, the coupling between your views won't become problematic, and you'll be able to create flexible, maintainable code (far more maintainable than if you were to use global variables, as then you'd really lose encapsulation).
In light of all that, let's examine a quick example. Let's say you have views A, B, and C that all use model X, but you're building A, B and C in totally different places in the code (making it difficult to share X between them).
1) First, I'd look at why A, B, and C are being built in such different spots, and see if I can't move them closer together.
2) If they have to be built so far apart, I'd then look at whether they have something in common I can exploit; for instance, do all those spots all share some related object? If so, then maybe we can put X on that object to share it with all our views.
2) If there's no connection either in code placement or in common variables between A, B, and C, then I'd have to ask "should I really be sharing a model between them at all?"
Boring Story About Author:
When I first started using Backbone, I would often find myself arguing with my co-workers because I wanted to make global variables, and they were firmly against them. I tried to explain to them that if I couldn't use globals I'd have to pass models from view A to view B to view C to view D to view E, when only E would actually need that model. Such a waste!
Except (as I've since learned), I was wrong. Globals are a horrible idea, at least from a maintainability standpoint. Once you start using them, you quickly have no idea what code is affecting what, because you lose the encapsulation you'd normally have between views that use that global variable. And if you're working on a meaningfully large project (ie. one that is worth using Backbone for) encapsulation is one of the only ways to keep your code sane.
Having used Backbone a lot in the time in between, I now firmly believe that the right answer is to pass your model to your view as you create it. This might mean passing models between intermediary views that don't directly use them, but doing that will give you much better, more maintainable code than if you passed models around via globals. As awkward as it may feel at first, passing the models in to the views when you create them is proper practice.
Once you get more familiar with Backbone you will likely find that you only rarely need to pass a model through more than one intermediary view. In fact, you'll likely notice that whenever you find yourself having to pass a model between more than one view that you've detected a "code smell", and that the real issue is that your code needs refactoring.
But as with everything else on Stack Overflow, your mileage may vary ;-)
Upvotes: 4