New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate Route Render APIs #418

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
10 participants
@chadhietala
Copy link
Member

chadhietala commented Dec 19, 2018

Rendered

Closes #304.

@rtablada

This comment has been minimized.

Copy link

rtablada commented Dec 19, 2018

I'm a HUGE 👍 on this (though we do have some legacy features that rely on route rendering).

This really simplifies the route/template and rendering relationship across the broader ecosystem. Especially when advising older projects that rely heavily on Route.prototype.render IMO having a dedicated migration guide and deprecating is better than our current silence (and support burden) in documentation.


From a migration strategy I think some migration guides around common scenarios which from experience route rendering can usually be replaced by one of a few strategies:

  1. Match the template name to the route (for the simple case where these got decoupled for some reason)
  2. Create a component and pass in attrs (in the case where a template may have been shared across multiple routes using the render method to populate
  3. Use a parent route and template (often when all children routes have the same UI populated but failed to take advantage of parent routing and outlets)
  4. Use components in a parent route (usually application) with a service tied to it to facilitate state population, changes, and communication
  5. Use wormholes to push components or UI fragments into what is a common use case for render + named outlets

@rtablada rtablada referenced this pull request Dec 19, 2018

Closed

Route actions #394

@Gaurav0

This comment has been minimized.

Copy link
Contributor

Gaurav0 commented Dec 19, 2018

@chadhietala Rendered link not working any more.

@Gaurav0

This comment has been minimized.

Copy link
Contributor

Gaurav0 commented Dec 19, 2018

We are not deprecating Route#templateName property, correct?

@jgwhite

This comment has been minimized.

Copy link

jgwhite commented Dec 20, 2018

I quickly grep’d the Heroku Dashboard code base to see how we’d be impacted by this. Turns out we use Route#render quite extensively — 38 calls in total.

The vast majority deal with rendering ancillary UI into top-level outlets (e.g. top-nav, action-bar). Using wormholes seems like an appropriate migration path for these.

The other usages are to switch between different templates for an error route. Presumably the appropriate migration path for this is to turn those templates into components.

@chadhietala

This comment has been minimized.

Copy link
Member

chadhietala commented Dec 20, 2018

@jgwhite yea this was typically the case.

@Gaurav0 I need to check. If not I need to update this RFC and call out that you can still have different route templates.

@jessica-jordan jessica-jordan referenced this pull request Dec 20, 2018

Merged

The Ember Times - Issue No. 78 #3733

6 of 16 tasks complete
@knownasilya

This comment has been minimized.

Copy link
Contributor

knownasilya commented Dec 21, 2018

Here's a scenario that uses render/renderTemplate https://github.com/embermap/ember-cli-tailwind/blob/master/app/instance-initializers/ember-cli-tailwind.js#L8, although this might be the wrong tool for the job, but I'm unsure what the right tool would be.

@jessica-jordan jessica-jordan referenced this pull request Jan 1, 2019

Merged

Ember Times - Issue No. 79 #3750

7 of 16 tasks complete
@benedikt

This comment has been minimized.

Copy link

benedikt commented Jan 3, 2019

In one of my projects I use renderTemplate and render to replace a sidebar layout of a parent route for certain sub-routes. How would I achieve a similar setup without those methods?

I tried to visualize the situation in the image below. I hope it makes sense in combination with the code snippets.

// router
this.route('authenticated', { path: '' }, function() {
  this.route('campaigns', { resetNamespace: true }, function() {
    this.route('campaign', { path: ':campaign_id' }, function() {
      this.route('messages', function() {
        this.route('message', { path: ':message_id' });
      });
    });
  });
});
// campaign.messages 
renderTemplate() {
  this.render({ into: 'authenticated' });
}

layout

@lifeart

This comment has been minimized.

Copy link

lifeart commented Jan 5, 2019

I use renderTemplate for route templates hot-reloading in ember-ast-hot-loader - https://github.com/lifeart/ember-ast-hot-load/blob/master/addon/services/hot-loader.js#L143
If we drop it, we need some way to trigger route template rerendering.

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 5, 2019

We make a lot of use of render and renderTemplate as well, to render templates in different places. For example dialogs and fullscreen components that can’t be part of the html tree but have to be below it instead. We have a few named outlets for this in application.hbs. I don’t see how this can be replaced with components, as there isn’t just a single one for each outlet but there is a number of components that has to be rendered there depending on the route. The only way for us to solve this would be to allow these things to be rendered in the tree css-wise I guess. In any case this would leave us with a huge architectural question.

@knownasilya

This comment has been minimized.

Copy link
Contributor

knownasilya commented Jan 5, 2019

@rmachielse You would use something like https://github.com/ef4/ember-elsewhere and create a component that has multiple components in it's template (for the multiple component scenario you mentioned).

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 5, 2019

@knownasilya yep, something like that and ember-wormholes are rightfully alternatives.
Yet I see renderTemplate as a much cleaner approach considering the amount of occurences we have of this. To me this feels like a major core feature whereas those addons feel like workarounds. Those would bloat our templates while renderTemplate keeps those concerns seperated.

@knownasilya

This comment has been minimized.

Copy link
Contributor

knownasilya commented Jan 6, 2019

Yeah maybe that is true about it being a type of work around, although things like ember-elsewhere are using public API (see this merged RFC #287) so they are very lightweight.

I do like the how ember-component-routes addon ("routable components" experiment) handles this, feels very clean: https://wongpeiyi.github.io/ember-component-routes/#/rendering. e.g.

import { ComponentRoute } from 'ember-component-routes';

export default ComponentRoute.extend({
  renderComponents() {
    this.renderComponent('app-menu', { outlet: 'sidebar' });
    this.renderComponent('post-page', { into: 'parent-page' });
  }
});

Where parent-page is a route name and the component is rendered into {{component-outlet}} (custom construct).

So maybe an alternative API should be proposed, to at least allow experimentation like above.

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 6, 2019

That one looks cleaner indeed. However, as long as ember has controllers and routes, renderTemplate looks like a very valid need and I don't see any big advantages in getting rid of it. I do see the complexity argument and I do recognize that this is probably true for smaller applications. However for larger applications like ours, renderTemplate reduces complexity big time, as most developers can keep on developing templates and controllers as always, while the template may be rendered out of the tree. So yes, maybe this is an advanced feature that shouldn't distract beginning developers too much, but it is one that makes our life much easier.

@LevelbossMike

This comment has been minimized.

Copy link

LevelbossMike commented Jan 7, 2019

@rmachielse what's the benefit of using renderTemplate over a wormhole like functionality like ember-elsewhere, ember-wormhole or in-element?

fwiw I'm very much in favor of deprecating this as removing the api encourages to use declarative templates that tell a developer where stuff is rendered by just looking at the template files rather than digging through the routes.

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 7, 2019

@LevelbossMike the separation of concerns is the most valuable thing to me. I think the decision of where to render a template should not be a responsibility of the template itself. Also in our case it allows us to reuse templates, without having to change anything in the template itself.

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 7, 2019

If this functionality is considered to be too far away from core principles, could it be extracted to an addon? Not one that extends support temporarily but one that can be maintained for longer time? Or does it depend on internal api's too much?

@knownasilya

This comment has been minimized.

Copy link
Contributor

knownasilya commented Jan 7, 2019

Deprecation doesn't mean it will be removed right away, so it should be around until Ember 4.0, which is still probably a year away most likely (imo).

@rmachielse

This comment has been minimized.

Copy link

rmachielse commented Jan 7, 2019

Understood, but I would like a future-proof solution.

@chadhietala

This comment has been minimized.

Copy link
Member

chadhietala commented Jan 7, 2019

I have updated the RFC with clearer examples on how to migrate.

@rmachielse: #287 introduced a public API to do what ember-elsewhere / ember-wormhole do. It was created specifically for the cases where you do need to escape the existing DOM hierarchy and render somewhere else. This is great for things like modals, adding to navigation depending on downstream logic, etc. In the cases where you do need access a controller for a specific template and don't want to refactor to a component you can inject controllers onto other objects. The opinion of the core team is that components are the way templates / functionality should be shared and reused.

@Gaurav0 templateName requires another RFC and likely some investigation of migration strategy.

@benedikt

This comment has been minimized.

Copy link

benedikt commented Jan 7, 2019

@chadhietala Thanks for adding more examples!

I can see how {{in-element}} would work to replace the use of named outlets. Would that also work to render content in main outlets higher up in the hierarchy?

In your hierarchy escaping example, would it be possible to reliably render into the section#content element, effectively replacing the main outlet, from deeper down in the hierarchy?

It feels a bit weird to replace the contents of the wrapping element, as it feels like it would remove the outlet.

(Please forgive me my ignorance about the details of how {{in-element}} works.)

@lifeart

This comment has been minimized.

Copy link

lifeart commented Jan 7, 2019

@chadhietala any public way to force route template rerender without renderTemplate call?

@chadhietala

This comment has been minimized.

Copy link
Member

chadhietala commented Jan 7, 2019

@lifeart

This comment has been minimized.

Copy link

lifeart commented Jan 7, 2019

@chadhietala of course! I made ember-ast-hot-reload addon. And it allow users to hot-reload components (using PoC from ember tests) and route templates, using renderTemplate method. How I can replace it if it will be deprecated?

Code examples above don't deal with route level templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment