Quick context: Application view has 2 outlets. One for a toolbar. The other for the routable "main" view hierarchy.
app -- main
\-- toolbar
I need some buttons in the toolbar to trigger events in the "main" view. Not update any data in any model. I simply instruct it to trigger some changes to a drawing library that the view is presenting. Clearing the canvas, resetting zoom value and such.
In 1.0 pre2 and earlier I have used actions and router.get('someController.view') to get access to the view I want and trigger the action/method/event. Hardly the pinnacle of application design but it worked fine.
This option is now gone and I am at a loss for a good alternative. What mechanism should I use when communicating between views that are not in a child/parent hierarchy? Everything I have come up with is clunky and triggers my sense that "Ember has a better way".
In short I want:
Poor Options I am considering:
The toolbar is very much an application level concern but it does have some buttons that need to instruct specific views. One option I see within Ember is to nest the toolbar under the "main" view. This seems wrong for some of it's other functions.
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of. This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
I could make the drawing library an application global as App.Drawing or something but that does also seems bad. It would also mean that the actions still would not be able to make use of any data in the view to update the drawing library with.
Any suggestions?
What mechanism should I use when communicating between views that are not in a child/parent hierarchy?
In a typical ember application this communication should happen between controllers. Otherwise "Poor Option 2" is on the right track:
Communication could be handled by a controller (and possibly even a model) that would hold properties that the toolbar sets and the "listening" view reacts to and resets the value of.
Consider using two controllers. Toolbar actions will target the ToolbarController
, which is responsible for maintaining the toolbar's state and for changing main in response to user action. ToolbarController
should declare a dependency on MainController
via the needs
property. For example:
App.ToolbarController = Ember.Controller.extend({
needs: ['main'],
buttonOneGotAllPressed: function() {
main = this.get('controllers.main');
main.turnOffAnOption();
main.makeSomeOtherChange();
}
});
Now MainController
can be focused on the state of MainView. It should not be aware of ToolbarController
or it's buttons.
This sounds like abuse of the controller and model purposes and like a pretty poor event listener setup.
Agreed it would likely be an abuse of model purposes but it is exactly what controllers are for.
This is definitely not an event-listener setup, but that does not seem a good fit in your case. The toolbar you describe seems to exist only to interact with the main view, so it makes sense to have a toolbar controller that depends on main and interacts with it directly.
If the components are truly decoupled then an observer (Pub/Sub) pattern might be more appropriate. See How to fire an event to Ember from another framework if that's of interest.
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