4

The ember Router provides for a nice branching structure of resources (in my case content for a resource nested inside a panel in a parent page), for example:

   app
   / \
  A   B
 /   / \
C   D   E

But my problem is that under two of my pages I link back to common content, for example both pages A & B have content C in a panel:

   app
   / \
  A   B
   \ / \
    C   D

"C" has to have two different routes as I want to be able to specify mysite.com/A/C as being different from mysite.com/B/C - both would have "C" in a panel but the surrounding page would be different. But the controller and to a large extent the template for C is the same in both places,.. so how would I go about having two different routes like this that share a common controller and template, (and for bonus points, how would I then inform the template what the parent was so I could make subtle adjustments based on that?)

Zuur
  • 101
  • 1
  • 6
  • Possible duplicate of: http://stackoverflow.com/questions/16331690/emberjs-sharing-a-controller-template-for-different-routes – gorner Sep 03 '14 at 12:59
  • Basically, you're getting confused with the route hierarchy (which is always a tree, never a graph, and defines routes and subroutes), and controllers which exist in a 1-1 relationships with routes, and a possible object hierarchy (which defines superclasses and subclasses). As one answer points out, sharing logic between controllers in this case is best handled by factoring it out into a superclass. The superclass does not have an instance, nor a route, it is simply a cluster of logic (in this case derived form `ObjectController`) that can be shared between multiple controllers. –  Sep 03 '14 at 15:54

2 Answers2

1

If they are mostly the same, but slightly different I'd create base Controller/Route/View and extend from them for each individual route. Namespacing each route slightly different.

App.Router.map(function(){
  this.resource('A', function(){
    this.resource('AC', function(){

    });
  });
  this.resource('B', function(){
    this.resource('BC', function(){

    });
    ...
  });
});



App.BaseCRoute = Em.Route.extend({
  model: function(){
    return { foo: 'bar'};
  }
});

App.ACRoute = App.BaseCRoute.extend({
  // use the same model hook
});

then the pattern continues for the controllers and views, with the shared logic existing in the base class, and the unique logic existing in the extended class. If you want to share the template, you can define the template to use in the view, or specify it in the renderTemplate hook of the route.

Kingpin2k
  • 47,277
  • 10
  • 78
  • 96
0

You're free to extend (or even alias) your own controllers, so you could do something like this:

App.CController = Ember.Controller.extend({...})

App.ACController = App.CController.extend()
// or (I believe) equivalently, if you don't need to make any /A/C-specific adjustments:
// App.ACController = App.CController

App.BCController = App.CController.extend()

That will enable the Ember resolver to easily find the correct controllers for your routes even though you're only defining the controller code once.

In terms of templates, you can override renderTemplate in your routes (as suggested in the other question I noted as a possible duplicate), or you could just define both of the "default" templates as calling the same partial. So templates/c.hbs would contain your actual template, while templates/a/c.hbs and templates/b/c.hbs could just contain a single line, {{partial 'c'}}.

gorner
  • 552
  • 2
  • 8