Complex nested application design


#1

Hello. I’m working on a pretty standard Ember app (lots of routes, views, controllers), but I’ve come across a scenario I don’t know how to structure correctly.

I’m trying to write a little widget which encapsulates what feels to me like a “mini” Ember app all on its own. An illustrative example is a list widget which you can drill down and inspect the contents of by clicking on items. I want the user to navigate around inside of this component (drilling down into and backing out of items in this list), and I want to embed this widget as a component or subview as a small part of my larger Ember app.

Should this be a component? If so, how do I keep track of the various states of this component (whether an item is to be shown or the list), without leveraging Ember routes.

Should this be some combination of standard route / controller / view? If so, how do I keep this widget route away from the url that represents the main application’s route?


#2

I have some reusable widgets like you describe, with rich enough behavior that they have their own routes.

What I do is basically metaprogrammed nested routes. This involves writing a reusable function that sets up all your child routes wherever they are needed within the wider route map and dynamically creates named Route classes to match.

Here’s a snippet to illustrate the basic idea:

function orderEditors() {
  var place = this.parent.classify().replace(/\./g, '');
  App[place + 'OrdersRoute'] = OrdersRoute;
  App[place + 'NewOrderRoute'] = NewOrderRoute;
  App[place + 'OrdersHoldRoute'] = HoldRoute;
  App[place + 'OrdersGroupRoute'] = GroupRoute;
  App[place + 'NewOrderGroupRoute'] = GroupRoute;

  this.resource(this.parent + '.orders', {path: '/orders/:order_id'}, function() {
    this.route('hold');
    this.route('group');
  });
  return this.resource(this.parent + '.new_order', {path: '/new_order/:type'}, function() {
    this.route('group');
  });
};

I call that function within any other resource that needs to support my editor components. Like:

App.Router.map(function(){
  this.resource("foo", function(){
    orderEditors.apply(this);
  });
});
```

The other thing to keep in mind that is these "portable" routes need to be explicit about what controller and template they want to use, because they're going to get invoked with various different names and otherwise will get various different defaults.

#3

Did you ever come up with a valid solution to the multiple nested application scenario?