rfcs
rfcs copied to clipboard
Spread Operator In Templates
Problem
Currently there is no way to pass dynamic parameters to certain Template Helpers. I'll call out the query-params
helper in this case as an example.
Typically we'd use it in the following way:
{{#link-to 'route' (query-params sort="asc" status="complete")}}
Which would give us a link to /route?sort=asc&status=complete
This works well, but there is no way to pass a set of dynamic values to the helper. If we have the following in a component:
params: {
sort: 'asc',
status: 'complete'
}
You can't destructure the parameters in the template:
{{#link-to 'route' (query-params params)}}
Solution
We should add support for a spread operator (similar to the one in javascript) for use in templates. I would see something like this looking like:
{{#link-to 'route (query-params ...params)}}
Which would end up being the same as:
{{#link-to 'route' (query-params sort="asc" status="complete")}}
But would allow us to change params
and have it reflect in the helper.
I've been hoping we would see a spread or splat operator for a long time. There is actually an open PR in the handlebars repo https://github.com/wycats/handlebars.js/pull/1149. In theory it should be compatible with the query-params
helper.
A really huge use case is being able to use the component helper in a much more dynamic way. We lost this ability when Ember.ContainerView
was removed and haven't fully got it back. Eg:
{{#each dynamicComponents as |compInfo|}}
{{component compInfo.class ...compInfo.args}}
{{/each}}
Another solution is to make this work: {{#link-to 'route' (query-params params)}}
The (query-params)
helper could accept the first positional param as the hash;
export default Ember.Helper.helper(function(params, hash) {
let queryParams = Ember.assign({}, params[0], hash);
// ...
});
Of course this only addresses the query params problem and not other uses cases...
@workmanw I'll keep an eye on that PR, we might just have to wait until that lands in handlebars. I agree that it would be great to be able dynamically insert components too!
@Panman8201 For my use case modifying the query-params
helper directly would solve my problem and may be a good short term fix, but I think the spread operator would be a much more powerful addition.
My use case is:
{{yield
(hash foo=(component "foo") ...this.moreThings)
}}
@amk221 You could use @tchak's ember-merge-helper
:
{{yield
(merge this.moreThings foo=(component "foo"))
}}
One issue with above helper (AFAICT) is that it does not track changes on moreThings
, as this is the full implementation:
import { helper } from '@ember/component/helper';
import { assign } from '@ember/polyfills';
export default helper(function(hashes, hash) {
// return assign(Object.create(null), ...hashes, hash);
return assign({}, ...hashes, hash);
});
The reason I created ember-merge-helper
is exactly to solve link-to
/query-params
problem :)
My use case would be:
{{#each components as |component|}}
{{component component.name ...component.params}}
{{/each}}
Another plus side for being able to splat arguments and similar is that it makes one variant of higher-order components quite nice: you can just wrap an existing component, make some template-layer tweaks/wrapping and forward all the inbound arguments to it.
I have the same use case as @workmanw @amk221 and @basz and I totally agree with @chriskrycho : a spread operator would be the best friend of the {{component}}
helper 🙂
@chriskrycho Sorry to bother you about this old one, but do you know what is the status of this ? I mean, I've searched a bit, but I can't find if today we can splat arguments, passing them to the {{component}}
helper?
This seems like a good idea, but we need an RFC to move it forward. Is there anything I can do to help facilitate?