diff --git a/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts b/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts index 904990bbb2b..85f9683711c 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts +++ b/packages/@ember/-internals/glimmer/tests/integration/application/debug-render-tree-test.ts @@ -222,10 +222,13 @@ if (ENV._DEBUG_RENDER_TREE) { } renderTemplate(_: Controller, { showHeader }: Model): void { - this.render(); + expectDeprecation(() => this.render(), /Usage of `render` is deprecated/); if (showHeader) { - this.render('header', { outlet: 'header' }); + expectDeprecation( + () => this.render('header', { outlet: 'header' }), + /Usage of `render` is deprecated/ + ); } else { expectDeprecation( () => this.disconnectOutlet('header'), diff --git a/packages/@ember/-internals/glimmer/tests/integration/application/rendering-test.js b/packages/@ember/-internals/glimmer/tests/integration/application/rendering-test.js index 7efd7402d5b..2198da8943c 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/application/rendering-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/application/rendering-test.js @@ -464,11 +464,13 @@ moduleFor( 'route:application', Route.extend({ renderTemplate() { - this.render(); - this.render('nav', { - into: 'application', - outlet: 'nav', - }); + expectDeprecation(() => { + this.render(); + this.render('nav', { + into: 'application', + outlet: 'nav', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -613,7 +615,10 @@ moduleFor( }, renderTemplate(controller, model) { - this.render({ controller: model.color, model }); + expectDeprecation( + () => this.render({ controller: model.color, model }), + /Usage of `render` is deprecated/ + ); }, }) ); @@ -659,7 +664,10 @@ moduleFor( }, renderTemplate(controller, model) { - this.render('common', { controller: 'common', model }); + expectDeprecation( + () => this.render('common', { controller: 'common', model }), + /Usage of `render` is deprecated/ + ); }, }) ); @@ -672,7 +680,10 @@ moduleFor( }, renderTemplate(controller, model) { - this.render('common', { controller: 'common', model }); + expectDeprecation( + () => this.render('common', { controller: 'common', model }), + /Usage of `render` is deprecated/ + ); }, }) ); diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index f57c581ef8c..7e2c3474173 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -20,7 +20,7 @@ import { Object as EmberObject, typeOf, } from '@ember/-internals/runtime'; -import { isProxy, lookupDescriptor } from '@ember/-internals/utils'; +import { isProxy, lookupDescriptor, symbol } from '@ember/-internals/utils'; import Controller from '@ember/controller'; import { assert, deprecate, info, isTesting } from '@ember/debug'; import { ROUTER_EVENTS } from '@ember/deprecated-features'; @@ -49,6 +49,7 @@ import generateController from './generate_controller'; import EmberRouter, { QueryParam } from './router'; export const ROUTE_CONNECTIONS = new WeakMap(); +const RENDER = symbol('render') as string; export function defaultSerialize( model: {}, @@ -1485,6 +1486,29 @@ class Route extends EmberObject implements IRoute { return route && route.currentModel; } + /** + `this[RENDER]` is used to render a template into a region of another template + (indicated by an `{{outlet}}`). + + @method this[RENDER] + @param {String} name the name of the template to render + @param {Object} [options] the options + @param {String} [options.into] the template to render into, + referenced by name. Defaults to the parent template + @param {String} [options.outlet] the outlet inside `options.into` to render into. + Defaults to 'main' + @param {String|Object} [options.controller] the controller to use for this template, + referenced by name or as a controller instance. Defaults to the Route's paired controller + @param {Object} [options.model] the model object to set on `options.controller`. + Defaults to the return value of the Route's model hook + @private + */ + [RENDER](name?: string, options?: PartialRenderOptions) { + let renderOptions = buildRenderOptions(this, name, options); + ROUTE_CONNECTIONS.get(this).push(renderOptions); + once(this._router, '_setOutlets'); + } + /** A hook you can use to render the template for the current route. @@ -1521,7 +1545,7 @@ class Route extends EmberObject implements IRoute { */ renderTemplate(_controller: any, _model: {}) { // eslint-disable-line no-unused-vars - this.render(); + this[RENDER](); } /** @@ -1652,9 +1676,16 @@ class Route extends EmberObject implements IRoute { @public */ render(name?: string, options?: PartialRenderOptions) { - let renderOptions = buildRenderOptions(this, name, options); - ROUTE_CONNECTIONS.get(this).push(renderOptions); - once(this._router, '_setOutlets'); + deprecate(`Usage of \`render\` is deprecated. Route: \`${this.routeName}\``, false, { + id: 'route-render-template', + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x/#toc_route-render-template', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); + this[RENDER](name, options); } /** diff --git a/packages/ember/tests/routing/model_loading_test.js b/packages/ember/tests/routing/model_loading_test.js index 9a9151286e8..0f71d5c5fe1 100644 --- a/packages/ember/tests/routing/model_loading_test.js +++ b/packages/ember/tests/routing/model_loading_test.js @@ -214,7 +214,10 @@ moduleFor( Route.extend({ controllerName: 'myController', renderTemplate() { - this.render('alternative_home'); + expectDeprecation( + () => this.render('alternative_home'), + /Usage of `render` is deprecated/ + ); }, }) ); diff --git a/packages/ember/tests/routing/template_rendering_test.js b/packages/ember/tests/routing/template_rendering_test.js index df0f00a8ea1..f33f0c72dfc 100644 --- a/packages/ember/tests/routing/template_rendering_test.js +++ b/packages/ember/tests/routing/template_rendering_test.js @@ -76,7 +76,7 @@ moduleFor( 'route:home', Route.extend({ renderTemplate() { - this.render('homepage'); + expectDeprecation(() => this.render('homepage'), /Usage of `render` is deprecated/); }, }) ); @@ -93,7 +93,7 @@ moduleFor( 'route:home', Route.extend({ renderTemplate() { - this.render('homepage'); + expectDeprecation(() => this.render('homepage'), /Usage of `render` is deprecated/); }, }) ); @@ -121,7 +121,7 @@ moduleFor( Route.extend({ controllerName: 'foo', renderTemplate() { - this.render('homepage'); + expectDeprecation(() => this.render('homepage'), /Usage of `render` is deprecated/); }, }) ); @@ -159,7 +159,10 @@ moduleFor( 'route:homepage', Route.extend({ renderTemplate() { - this.render({ controller: 'home' }); + expectDeprecation( + () => this.render({ controller: 'home' }), + /Usage of `render` is deprecated/ + ); }, }) ); @@ -199,7 +202,7 @@ moduleFor( 'route:home', Route.extend({ renderTemplate() { - this.render('homepage'); + expectDeprecation(() => this.render('homepage'), /Usage of `render` is deprecated/); }, }) ); @@ -219,9 +222,11 @@ moduleFor( 'route:home', Route.extend({ renderTemplate() { - this.render('bio', { - model: { name: 'emberjs' }, - }); + expectDeprecation(() => { + this.render('bio', { + model: { name: 'emberjs' }, + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -266,10 +271,12 @@ moduleFor( templateName: 'the_real_home_template', actions: { showAlert() { - this.render('alert', { - into: 'home', - outlet: 'alert', - }); + expectDeprecation(() => { + this.render('alert', { + into: 'home', + outlet: 'alert', + }); + }, /Usage of `render` is deprecated/); }, }, }) @@ -299,7 +306,7 @@ moduleFor( Route.extend({ templateName: 'alert', renderTemplate() { - this.render({}); + expectDeprecation(() => this.render({}), /Usage of `render` is deprecated/); }, }) ); @@ -420,7 +427,10 @@ moduleFor( 'route:middle.bottom', Route.extend({ renderTemplate() { - this.render('middle/bottom', { into: 'top' }); + expectDeprecation( + () => this.render('middle/bottom', { into: 'top' }), + /Usage of `render` is deprecated/ + ); }, }) ); @@ -454,8 +464,10 @@ moduleFor( 'route:home', Route.extend({ renderTemplate() { - this.render('person/profile'); - this.render('person/details', { into: 'person/profile' }); + expectDeprecation(() => { + this.render('person/profile'); + this.render('person/details', { into: 'person/profile' }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -485,11 +497,13 @@ moduleFor( 'route:posts', Route.extend({ renderTemplate() { - this.render(); - this.render('posts/menu', { - into: 'application', - outlet: 'menu', - }); + expectDeprecation(() => { + this.render(); + this.render('posts/menu', { + into: 'application', + outlet: 'menu', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -637,7 +651,10 @@ moduleFor( }, renderTemplate() { - this.render('shared', { controller: 'shared' }); + expectDeprecation( + () => this.render('shared', { controller: 'shared' }), + /Usage of `render` is deprecated/ + ); }, }); @@ -707,17 +724,19 @@ moduleFor( 'route:posts', Route.extend({ renderTemplate() { - this.render('posts/menu', { - into: 'application', - outlet: 'menu', - }); + expectDeprecation(() => { + this.render('posts/menu', { + into: 'application', + outlet: 'menu', + }); - this.render(); + this.render(); - this.render('posts/footer', { - into: 'application', - outlet: 'footer', - }); + this.render('posts/footer', { + into: 'application', + outlet: 'footer', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -782,10 +801,12 @@ moduleFor( Route.extend({ actions: { showModal() { - this.render('posts/modal', { - into: 'application', - outlet: 'modal', - }); + expectDeprecation(() => { + this.render('posts/modal', { + into: 'application', + outlet: 'modal', + }); + }, /Usage of `render` is deprecated/); }, hideModal() { expectDeprecation( @@ -806,9 +827,11 @@ moduleFor( Route.extend({ actions: { showExtra() { - this.render('posts/extra', { - into: 'posts/index', - }); + expectDeprecation(() => { + this.render('posts/extra', { + into: 'posts/index', + }); + }, /Usage of `render` is deprecated/); }, hideExtra() { expectDeprecation( @@ -912,10 +935,12 @@ moduleFor( Route.extend({ actions: { showModal() { - this.render('posts/modal', { - into: 'application', - outlet: 'modal', - }); + expectDeprecation(() => { + this.render('posts/modal', { + into: 'application', + outlet: 'modal', + }); + }, /Usage of `render` is deprecated/); }, hideModal() { expectDeprecation( @@ -965,7 +990,7 @@ moduleFor( } ['@test Route silently fails when cleaning an outlet from an inactive view'](assert) { - assert.expect(3); // handleURL + assert.expect(4); // handleURL this.addTemplate('application', '{{outlet}}'); this.addTemplate('posts', "{{outlet 'modal'}}"); @@ -990,7 +1015,10 @@ moduleFor( ); }, showModal() { - this.render('modal', { into: 'posts', outlet: 'modal' }); + expectDeprecation( + () => this.render('modal', { into: 'posts', outlet: 'modal' }), + /Usage of `render` is deprecated/ + ); }, hideModal() { expectDeprecation( @@ -1012,7 +1040,9 @@ moduleFor( } ['@test Specifying non-existent controller name in route#render throws'](assert) { - expectDeprecation('Usage of `renderTemplate` is deprecated.'); + expectDeprecation( + /(Usage of `renderTemplate` is deprecated|Usage of `render` is deprecated)/ + ); assert.expect(2); this.router.map(function () { @@ -1074,11 +1104,13 @@ moduleFor( 'route:application', Route.extend({ renderTemplate() { - this.render(); - this.render('modal', { - into: 'application', - outlet: 'other', - }); + expectDeprecation(() => { + this.render(); + this.render('modal', { + into: 'application', + outlet: 'other', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -1105,11 +1137,13 @@ moduleFor( 'route:application', Route.extend({ renderTemplate() { - this.render(); - this.render('modal', { - into: 'application', - outlet: 'other', - }); + expectDeprecation(() => { + this.render(); + this.render('modal', { + into: 'application', + outlet: 'other', + }); + }, /Usage of `render` is deprecated/); }, actions: { banish() { @@ -1153,11 +1187,13 @@ moduleFor( 'route:application', Route.extend({ renderTemplate() { - this.render(); - this.render('modal', { - into: 'application', - outlet: 'other', - }); + expectDeprecation(() => { + this.render(); + this.render('modal', { + into: 'application', + outlet: 'other', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -1180,10 +1216,12 @@ moduleFor( Route.extend({ actions: { launch() { - this.render('modal', { - into: 'application', - outlet: 'other', - }); + expectDeprecation(() => { + this.render('modal', { + into: 'application', + outlet: 'other', + }); + }, /Usage of `render` is deprecated/); }, }, }) @@ -1221,14 +1259,16 @@ moduleFor( 'route:app', Route.extend({ renderTemplate() { - this.render('app', { - outlet: 'app', - into: 'application', - }); - this.render('common', { - outlet: 'common', - into: 'app', - }); + expectDeprecation(() => { + this.render('app', { + outlet: 'app', + into: 'application', + }); + this.render('common', { + outlet: 'common', + into: 'app', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -1237,10 +1277,12 @@ moduleFor( 'route:sub', Route.extend({ renderTemplate() { - this.render('sub', { - outlet: 'sub', - into: 'app', - }); + expectDeprecation(() => { + this.render('sub', { + outlet: 'sub', + into: 'app', + }); + }, /Usage of `render` is deprecated/); }, }) ); @@ -1282,10 +1324,12 @@ moduleFor( Route.extend({ actions: { openLayer() { - this.render('layer', { - into: 'application', - outlet: 'modal', - }); + expectDeprecation(() => { + this.render('layer', { + into: 'application', + outlet: 'modal', + }); + }, /Usage of `render` is deprecated/); }, close() { expectDeprecation( @@ -1328,7 +1372,7 @@ moduleFor( 'route:root', Route.extend({ renderTemplate() { - this.render('exports/root'); + expectDeprecation(() => this.render('exports/root'), /Usage of `render` is deprecated/); }, }) ); @@ -1337,7 +1381,10 @@ moduleFor( 'route:root.index', Route.extend({ renderTemplate() { - this.render('exports/index'); + expectDeprecation( + () => this.render('exports/index'), + /Usage of `render` is deprecated/ + ); }, }) ); @@ -1360,10 +1407,12 @@ moduleFor( Route.extend({ actions: { openLayer() { - this.render('layer', { - into: 'application', - outlet: 'modal', - }); + expectDeprecation(() => { + this.render('layer', { + into: 'application', + outlet: 'modal', + }); + }, /Usage of `render` is deprecated/); }, }, }) @@ -1480,10 +1529,12 @@ moduleFor( Route.extend({ actions: { showModal() { - this.render({ - outlet: undefined, - parentView: 'application', - }); + expectDeprecation(() => { + this.render({ + outlet: undefined, + parentView: 'application', + }); + }, /Usage of `render` is deprecated/); }, hideModal() { expectDeprecation( diff --git a/tests/docs/expected.js b/tests/docs/expected.js index 6b265de0ec7..33df88a6323 100644 --- a/tests/docs/expected.js +++ b/tests/docs/expected.js @@ -556,6 +556,7 @@ module.exports = { 'testing', 'textarea', 'then', + 'this[RENDER]', 'throttle', 'title', 'to',