I have an application that does CRUD for a Collection
of Models
. There is a DisplayView
for each model that is always visible. There is also an EditView
that is visible only when the associated DisplayView
is clicked on.
The DisplayView
and EditView
appear inside of different parent views. Right now I am using the "event aggregator" pattern to tell my application to render the EditView
when a DisplayView
is clicked. Pattern described here: http://lostechies.com/derickbailey/2011/07/19/references-routing-and-the-event-aggregator-coordinating-views-in-backbone-js/
When one of my DisplayView
is clicked it fires an event that the parent of the EditViews
listens to. When it receives this event it renders the appropriate EditView
, based on the model for which the event was fired.
This works well for most of my application, but is particularly cumbersome when I want to have the EditView
change position based on the absolute position of the related DisplayView
in my application. Rather than have the DisplayView
directly control the position of the EditView
, it triggers a "please reposition yourself to these coordinates" event. Such direct communication doesn't feel like something that should be broadcast to the entire application. I'm starting to wonder if for my case I should just have a reference to the appropriate EditView
as a property of each DisplayView
rather than decoupling them.
The problem, as I said, is that they are rendered inside of different parent views. The DisplayViews
get rendered in the HeaderView
while the the EditViews
get rendered in the ContentView
.
How do others handle situations like this? The EditView
in some ways belongs to the DisplayView
, but that does not match the way my application's DOM is structured. Assuming I do create a direct link between each EditView
and DisplayView
, how would I handle show/hide of the EditView
? Would the DisplayView
also need a reference to the ContentView
container, which it would render explicitly with the appropriate EditView
as a parameter?
The Backbone.js Views specify how your data looks like. They represent model's data to the users. They can be used with any JavaScript template library. They handle users input events, bind events and methods, render model and collection and interact with users.
It is used to extend the Backbone.view class to create a custom view class. 2. It is used to instantiate the view by using new keyword. 3. It defines which element to be used as the view reference. 4. It represents the jQuery object for the view's element.
The Event on method is used to bind an event to an object and callback function. It executes the callback function whenever an event is fired. event: It is used to bind an object.
As much as you can, definitely avoid views holding references to parallel views (as oppose to parent / child views) and modifying each other, this can quickly turn into spaghetti and make your code much more fragile. Instead, the following patterns allow your different views to stay decoupled while still get the job done.
This is the one you mentioned. It works but like you mentioned is less than elegant because it broadcast itself in the global scope unnecessarily
make an object named editViewPosition
in your controller and expose methods to let the display view change the values of the editViewPosition. The EditView
could then listen for and observe changes in the editViewPosition
and update itself accordingly. The strength of this approach is that later you can have 5 different EditViews
all observing the same property editViewPosition
on your controller and update themselves accordingly, and there would be nothing you need to change in your DisplayView
for that to happen.
Instead of directly hooking up the views and calling methods on each other, you can allow the display view to have a delegate
property, which can be set by the controller to be the edit
view. When the DisplayView
wants its edit view updated, it will check if its delegate exists and implements a predefined function, if so, it will call the function. This approach is more coupled than the observer pattern but still allows a high degree of decoupling (and later for instance you can swap an entirely different view in there instead of your edit view and the program should still work.) Weakness of this approach is that you typically only have a single delegate, but it is more direct than any of the other patterns mentioned.
This is almost an extension to the delegate pattern. Basically you have an array of EditView
like objects in your display view, and whenever needed, your display view will go through the array and call method on each of those objects. This array would again be populated by your controller.
Personally, I'd most likely use the binding and observer pattern for your use case. In general, views that are parallel (no direct parent / child relationship) should not hold references to each other and should only communicate via a common controller / event / notification / other super-structure that they share.
There is another option, in addition to those enumerated by Tony, which is "bubbling up" an event that is triggered when the DisplayView
is clicked to the closest common parent view of the DisplayView
and EditView
. With the event you pass the coordinates of the display view and the model it represents. Then the common parent directly calls a method on the EditView
to reposition it and render the proper model. Thus no explicit references between parallel views, and no global variables.
Bubbling events up multiple view layers gets messy using backbone's built in trigger
and listenTo
methods, but the Backbone.Courier plugin makes it very straight forward:
https://github.com/rotundasoftware/backbone.courier
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With