Skip to content

Commit

Permalink
[BUGFIX beta] fix named outlet rendering in topmost view
Browse files Browse the repository at this point in the history
  • Loading branch information
ef4 committed Feb 12, 2015
1 parent 61ef0d2 commit 5f2fded
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 25 deletions.
12 changes: 2 additions & 10 deletions packages/ember-routing/lib/system/route.js
Original file line number Diff line number Diff line change
Expand Up @@ -1957,16 +1957,8 @@ function buildRenderOptions(route, namePassed, isDefaultRender, name, options) {

Ember.assert("An outlet ("+outlet+") was specified but was not found.", outlet === 'main' || into);

Ember.assert(
"You attempted to render into '" + into + "' but it was not found",
!into || Ember.A(route.router.router.state.handlerInfos).any(function(info) {
return Ember.A(info.handler.connections || []).any(function(conn) {
return conn.name === into;
});
})
);

if (into && into === parentRoute(route).routeName) {
var parent;
if (into && (parent = parentRoute(route)) && into === parentRoute(route).routeName) {
into = undefined;
}

Expand Down
50 changes: 35 additions & 15 deletions packages/ember-routing/lib/system/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ var EmberRouter = EmberObject.extend(Evented, {
_setOutlets: function() {
var handlerInfos = this.router.currentHandlerInfos;
var route;
var parentRoute;
var defaultParentState;
var liveRoutes = null;

Expand All @@ -201,21 +200,15 @@ var EmberRouter = EmberObject.extend(Evented, {

for (var i = 0; i < handlerInfos.length; i++) {
route = handlerInfos[i].handler;

var connections = (route.connections.length > 0) ? route.connections : [{
name: route.routeName,
outlet: 'main'
}];

var connections = normalizedConnections(route);
var ownState;
for (var j = 0; j < connections.length; j++) {
var appended = appendLiveRoute(liveRoutes, route, parentRoute, defaultParentState, connections[j]);
var appended = appendLiveRoute(liveRoutes, defaultParentState, connections[j]);
liveRoutes = appended.liveRoutes;
if (appended.ownState.render.name === route.routeName) {
ownState = appended.ownState;
}
}
parentRoute = route;
defaultParentState = ownState;
}
if (!this._toplevelView) {
Expand Down Expand Up @@ -994,6 +987,7 @@ function forEachQueryParam(router, targetRouteName, queryParams, callback) {
}

function findLiveRoute(liveRoutes, name) {
if (!liveRoutes) { return; }
var stack = [liveRoutes];
while (stack.length > 0) {
var test = stack.shift();
Expand All @@ -1007,31 +1001,57 @@ function findLiveRoute(liveRoutes, name) {
}
}

function appendLiveRoute(liveRoutes, route, parentRoute, defaultParentState, renderOptions) {
var targetName;
function appendLiveRoute(liveRoutes, defaultParentState, renderOptions) {
var target;
var myState = {
render: renderOptions,
outlets: create(null)
};
if (!parentRoute) {
liveRoutes = myState;
}
targetName = renderOptions.into || (parentRoute && parentRoute.routeName);
if (renderOptions.into) {
target = findLiveRoute(liveRoutes, renderOptions.into);
} else {
target = defaultParentState;
}
if (target) {
set(target.outlets, renderOptions.outlet, myState);
} else {
Ember.assert("You attempted to render into '" + renderOptions.into + "' but it was not found", !renderOptions.into);
liveRoutes = myState;
}
return {
liveRoutes: liveRoutes,
ownState: myState
};
}

function normalizedConnections(route) {
var connections = route.connections;
var mainConnections = [];
var otherConnections = [];

for (var i = 0; i < connections.length; i++) {
var connection = connections[i];
if (connection.outlet === 'main') {
mainConnections.push(connection);
} else {
otherConnections.push(connection);
}
}

if (mainConnections.length === 0) {
// There's always an entry to represent the route, even if it
// doesn't actually render anything into its own
// template. This gives other routes a place to target.
mainConnections.push({
name: route.routeName,
outlet: 'main'
});
}

// We process main connections first, because a main connection may
// be targeted by other connections.
return mainConnections.concat(otherConnections);
}


export default EmberRouter;
71 changes: 71 additions & 0 deletions packages/ember/tests/routing/basic_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3479,3 +3479,74 @@ QUnit.test("Can rerender application view multiple times when it contains an out

equal(Ember.$('#qunit-fixture').text(), "AppHello world", "third render");
});

QUnit.test("Can render into a named outlet at the top level", function() {
Ember.TEMPLATES.application = compile("A-{{outlet}}-B-{{outlet \"other\"}}-C");
Ember.TEMPLATES.modal = compile("Hello world");
Ember.TEMPLATES.index = compile("The index");

registry.register('route:application', Ember.Route.extend({
renderTemplate: function() {
this.render();
this.render('modal', {
into: 'application',
outlet: 'other'
});
}
}));

bootApplication();

equal(Ember.$('#qunit-fixture').text(), "A-The index-B-Hello world-C", "initial render");
});

QUnit.test("Can render into a named outlet at the top level, with empty main outlet", function() {
Ember.TEMPLATES.application = compile("A-{{outlet}}-B-{{outlet \"other\"}}-C");
Ember.TEMPLATES.modal = compile("Hello world");

Router.map(function() {
this.route('hasNoTemplate', { path: '/' });
});

registry.register('route:application', Ember.Route.extend({
renderTemplate: function() {
this.render();
this.render('modal', {
into: 'application',
outlet: 'other'
});
}
}));

bootApplication();

equal(Ember.$('#qunit-fixture').text(), "A--B-Hello world-C", "initial render");
});


QUnit.test("Can render into a named outlet at the top level, later", function() {
Ember.TEMPLATES.application = compile("A-{{outlet}}-B-{{outlet \"other\"}}-C");
Ember.TEMPLATES.modal = compile("Hello world");
Ember.TEMPLATES.index = compile("The index");

registry.register('route:application', Ember.Route.extend({
actions: {
launch: function() {
this.render('modal', {
into: 'application',
outlet: 'other'
});
}
}
}));

bootApplication();

equal(Ember.$('#qunit-fixture').text(), "A-The index-B--C", "initial render");

Ember.run(router, 'send', 'launch');

//debugger;
//router._setOutlets();
equal(Ember.$('#qunit-fixture').text(), "A-The index-B-Hello world-C", "second render");
});

0 comments on commit 5f2fded

Please sign in to comment.