3

I have an application scheme implemented in Ember that basically follows this layout:

layoyt

The concept is that the user can interact with features on the Map View (which is always present) and basic navigation occurs between various views in the Parent View and an arbitrary stack of Sub Views. The user can create new features on the map, edit existing ones etc.

The URL for a particular feature could be /features/123/edit

Since input into my interaction panels is very much dependent on interaction with the Map View (drawing a polygon, placing a marker etc.) my controllers for these views are setup to "need" the Map Controller. When a particular panel view is present interaction with the map should affect the panels in various ways.

My question is - how does one scale such tight controller coupling? I essentially need to switch between different Map modes based on which panel is currently active. I also, I believe, need to observe events on the map and act upon such events depending on the current active panel.

I setup a proof of concept where a certain Sub View Controller observes certain properties of the Map Controller (with for example .observes("controllers.map.activecoords") however, such an observer will continue to trigger even after the user has navigated away from the particular Sub view (i.e. as soon as the controller has been initialised). Must I setup and tear down such observers manually (i.e. using addObserver) when entering and leaving the route? Is this the right pattern? I've gotten the impression that requires that I manually remove all such observers during transitions to avoid unexpected behaviour and memory leaks.

Perhaps I'm going about this completely the wrong way? Are there any others patterns that fits my use case with an always present map with different states and intercommunication with interaction panels?

averas
  • 545
  • 1
  • 6
  • 15
  • A jsbin or some code will be helpful – Rigel Feb 26 '14 at 11:35
  • Rigel, I could try and extract some relevant sections from my setup, however, I'm more interested in how to achieve this conceptually rather than perhaps the exact operations involved. For example how controllers can be coupled with observers without things going on in the background when some controller views are not currently active.. – averas Feb 26 '14 at 11:54
  • I'm not sure if Ember has a common idiom for what you want. Ember tends to think of all of it's data (models, controllers, routes, templates, etc) as very hierarchical, where a single node is the focus. The first thing I would do (just to get it working), would be to place `active` properties on the controllers, and refuse to respond to actions if it's `false`. From there, I think it would just be trial and error to find a clean, working idiom. – GJK Feb 26 '14 at 15:00
  • I am not sure if this is right canditate for http://discuss.emberjs.com/ – Rigel Feb 27 '14 at 08:54
  • possible duplicate of [Accessing controllers from other controllers](http://stackoverflow.com/questions/14388249/accessing-controllers-from-other-controllers) – Paul Sweatte Apr 16 '14 at 19:30

1 Answers1

0

Perhaps the architecture of your application shouldn't be connecting controllers, but rather ask yourself "What is the model here, really?"

In each case, I think the model is your map, or at least its "contents". The features are really decorating the interaction with your central model, which is the map, underlying it all.

So really you have a single model here. You effectively have a map resource, and many feature routes on that resource, viewed from the URL/API.

The question is now not so much "how to manage a dependency hierarchy between controllers?" as "how do I manage a view and a subview on the same model?" which is answered quite simply in the standard ember nested route. Your outer view is always present and it has an outlet which is where your feature goes. How it's rendered is the inverse of how the standard nested route is rendered, but nevertheless it's the same pattern.

So, the TL;DR answer is... go through your model and the routes... use them to talk about your common data: the model is, afterall, your data, and the controllers and views are simply augmenting and enabling the user experience, presentation and interaction of them.

Most of these sorts of architectural problems can be resolved by moving the data up and down the hierarchy (template view / component / controller / route / model) until you find a place which is low enough to still be accessible to objects that need access to it, yet high enough that it makes sense by not being tightly bound with too many things, but still is in the right spot and "feels right".

If it's too high, you'll tend to be doing the wrong kind of work with your objects (ie controllers should not be mucking with view mechanics, models shouldn't really have presentation stuff in them, etc.

If it's too low, you'll tend to be doing too much work with the framework and you'll tend to be repeating yourself a lot... ie controllers will be doing a lot of work to get the data they need, for example.

Julian Leviston
  • 1,646
  • 10
  • 21