Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an action affect a sibling view without controller.get('view')?

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:

  • A toolbar-button to trigger an event
  • The main view to react to this and perform some updates on parts of itself.
  • The main view to NOT re-render in the Ember sense of the word as would through routing. It uses a drawing library and integrating all it's properties and behavior into Ember models and controllers would not be a lot of fun.
  • The toolbar and the main view share a parent view but are on different "branches".

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?

like image 840
Martin Westin Avatar asked Jan 30 '13 19:01

Martin Westin


1 Answers

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.

like image 140
Mike Grassotti Avatar answered Sep 20 '22 23:09

Mike Grassotti