Can one route be active multiple times simultaneously? (non singleton controller)

139 Views Asked by At

I would like to create a sliding UI in Ember JS, where the view for newly entered route partially slides over the previous route's view. It has to be possible for a route to be active multiple times with different models. See the end of this post for an example.

I'm having trouble fitting this into the Ember routing and rendering system. See this JSFiddle for what I've tried so far. It basically links to a new panel route with a random ID.

I created a containerOutlet helper that renders a new view into a ContainerView instead of a regular OutletView. This works, but when entering the same 'panel' route, it doesn't create a new controller/view pair but just changes the model on the current one.

Would it be possible to instead instantiate a new controller/view pair and render it 'into' the ContainerView outlet?

It feels like Ember wasn't designed for this and I'm fighting the system, so any tips or clarification would be helpful.


Example

Spotify has done this quite tastefully in their web player. I've attached a few screenshots to explain it better.

Basically when transitioning to a new route, it is rendered into a new 'layer' that slides over the previous route. Compare the before image and after image.

The previous view is still there, and the application transitions back when a previous route is clicked. This can be repeated unlimited times to create a layered UI that retains a 'route' history.


Code

function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

App = Ember.Application.create({});

App.Router.map(function () {
    this.route("panel", {
        path: "/:panel_id"
    });
});

App.IndexRoute = Ember.Route.extend({
    model: function () {
        random = getRandomInt(1, 10);
        return { nextPanelId: random };
    }
});

App.PanelRoute = Ember.Route.extend({
    model: function (params) {
        random = getRandomInt(1, 10);
        return {
            id: params.panel_id,
            nextPanelId: random
        };
    }
});

Ember.Handlebars.registerHelper('containerOutlet', function (property, options) {
    //(..)
    //Only this line has been changed
    return Ember.Handlebars.helpers.view.call(this, Ember.ContainerOutletView, options);
});

Ember.ContainerOutletView = Ember.ContainerView.extend({
    //For some reason it breaks when I remove this observer
    _currentViewWillChange: Ember.beforeObserver(function () {}, 'currentView'),

    _currentViewDidChange: Ember.observer(function () {
        this.pushObject(this.get('currentView'));
    }, 'currentView')
});
0

There are 0 best solutions below