It would be awesome if we had the ability to nest Ember apps within other Ember apps.
Right now, there are asserts that prevent this. I’m aware of some obvious places where things break down if you remove the asserts:
- Initializers will run for every Ember app
- Ember.Router.map stores an instance that is returned from every use & would be shared between apps
- Only one app should have the ability to update the URL - nested apps could be required to use
- Handlebars Helpers are global and not looked up through a resolver
- The outer app’s event dispatcher will trigger inner app’s views’ handlers (resulting in them being hit twice)
The first 4 things on that list are issues for multiple Ember apps on a page even if they are not nested. Only the event dispatcher is specifically related to the nesting.
Are there any other areas that need to be addressed for nested apps to work?
the shared Ember.Router.map issue is avoidable by always extending Ember.Router for each app before you call map.
I’ve opened a pull request showing a possible solution for the event dispatcher, and a very simple test showing nested app rendering and handling events.
What’s the use case for nested Ember Apps?
We’re working on an project (yapplabs/glazier) that has a “container and cards” architecture. The container is in Ember, and we would like to independently implement some cards in Ember with a fair degree of isolation. The ability to nest an Ember app would be an ideal organizational structure for this.
Another thing to keep in mind is that all of the “embedded” apps, and the parent app, will need to be using the same version of Ember.js. Because we still have some instances where state is stored on the
Ember global, instead of the app, (for example
Ember.View.views and the
guid counter), it’s possible there could be some action at a distance that will be very difficult to debug.
Modules help with this case, but now you’ve got the problem of each app on the page requiring a separate copy of Ember. Having them all be on the same version but getting pristine copies in memory is probably the optimal solution.
I implemented a similar construct, called a container and “gadgets”. These gadgets are 100% isolated (but can communicate with the same API on the backend of course) and runs an Ember app in an iframe. Works great.