-
-
Notifications
You must be signed in to change notification settings - Fork 408
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
Block let
template helper
#286
Conversation
Another alternative is to remove the blockers from making ember-let use public api only. The two blockers I can think of are one word components, and yielding N number of items. If modularizing and extracting core is the way forward, seems like that might be a equivalent proposal. |
@kellyselden that is indeed another possibility, albeit a harder sell on account of "yielding N number of items" meaning introducing a way to splat arguments (were you thinking something else?), which is its own can of worms ;P As for removing the "needs a dash" constraint on component names, it has been brought up before but I'm not sure what the general sentiment is. Internally, I believe the presence of a dash in the name is part of the heuristic to disambiguate between locals, helpers, and components. To touch on the modularity question, for some time now we had the idea of making a "standard library" addon with template helpers that could be shared amongst Emberjs and Glimmerjs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the block form of the let
helper is effectively the same thing as extracting that block into another component:
{{#let
firstName=(capizalize person.firstName)
lastName=(capitalize person.lastName)
}}
Account Details:
First Name: {{firstName}}
last Name: {{lastName}}
{{/let}}
becomes
{{person-tile firstName=(capizalize person.firstName) lastName=(capizalize person.lastName)}}
where the person-tile
's template looks like this:
Account Details:
First Name: {{firstName}}
last Name: {{lastName}}
Of course the capitalized strings could also be defined in JS land (e.g. using @kellyselden's ember-awesome-macros
) when passing the full person
into the component:
{{person-tile person=person}}
firstName: string.capitalize('person.firstName'),
lastName: string.capitalize('person.lastName')
Extracting new components for cases like this obviously leads to more code and more components but also doesn't introduce a new concept…
IMO this isn't so much a new concept as it is a less surprising version of an existing concept (the In addition, being able to bind values in the same template where they're being used is often more straightforward when you're essentially just using it to set up a computed value without declaring it on the JS file (which would be crucial in template-only components, as @locks mentioned). |
I'm also of like mind that this is the better version of |
I think what I'm trying to say is that this is the same as using a nested (template-only) component as both that and this |
- Refocused "Motivation" on the benefits of the block `let` - Move "Inline Form" to alternatives and expand - Move `with` deprecation to "Future Work" - Moved `if-let`, `let*` to "Future Work" - Introduce "Using Components" to "Alternatives"
I have updated the RFC with some of the feedback in the thread. I hope to have addressed your concerns! |
I'm moving this into Final Comment Period. |
Anyone can provide a convincing example of where this would be useful? Current RFC examples are bad (nonsense) or very unconvincing:
The whole argument of forgetting to use It appears that the |
@btecu in general, the use case for There are cases where bigger expressions come up naturally in Glimmer templates, most notably cases where you're yielding larger values like Glimmer's templating language is a very small programming language. It has no mutable variables (really no mutation of any kind) and all of its constructs are pure. But Glimmer has never eschewed the ability to declare variables, and in fact the entire point of the |
@btecu Here is a real world example where I used The component setup is quite verbose, and is used in the following |
@btecu I have a use case (private repo) where I |
I was searching through one of my code bases and found a {{#with (count-allowed group.themes 'view theme in dataset') as |allowedThemes|}} Since the count could be |
@knownasilya funny story, Glimmer treats only
|
Hey everyone! I did a Godfrey and a feature flag for this RFC is now in canary. You can try |
Using the `let` helper, this could be done like so: | ||
|
||
```handlebars | ||
{{#let (capizalize person.firstName) (capitalize person.lastName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
capitalize
is misspelled here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries. There's actually another misspelling further down in the document too on L125.
FWIW I recently tried to use Sorry I don't recall specifically what it was but I eventually resorted to an additional tiny component. I wasn't thrilled about it. |
@sdhull I've had that experience tons of times too. |
I agree with @btecu and @marcoow. This isn't really something that can't be solved with existing concepts (e.g. a computed or a component). Though I understand why one would want to do something like this (it seems like the "easy" thing to do in the described scenarios) I don't think the usage of helpers that encourage to put logic into templates should be encouraged by the framework via an "official" helper. especially for simple cases that would best be solved by a very simple computed. |
@LevelbossMike not so sure about this in every case. When you look at the example I posted in #286 (comment), how could that be done without
@marcoow I think this is not exactly true, because as far as I understand it a {{person-tile a=a b=b c=c d=d e=e firstName=(capizalize person.firstName) lastName=(capizalize person.lastName)}} Of course that get's even worse with more bindings... |
@simonihmig: yes, that's correct - a To be clear, I'm not totally opposed to this - I'm just not sure it's hugely valuable. To be fair, I also didn't even know the |
@simonihmig as you pointed out that's a use-case for the with-helper. I'm not convinced that |
As mentioned in the RFC, introducing bindings to the template is an existing concept, as that is what
Wouldn't this be an argument for Stealing an example from the Twiddle I linked above, I use {{#let
(component 'my-post' title=(concat post.title ' | The Ember.js Blog') content=post.content)
(hash
theme="dark"
enableComments=true
)
(hash
theme="responsive"
enableComments=false
)
as |prefilledPost darkTheme mobile|
}}
{{component prefilledPost options=darkTheme}}
{{component prefilledPost options=mobile}}
{{/let}} You could do this with a component, but it would still be done in that component's template and you lose the colocation. In general, this proposal does not change the immutable, declarative programming model of Ember templates. |
Two more thoughts regarding the latest points being discussed:
The same thoughts could be applied to JS itself: you could change the scope by calling another function, passing the new scope as args (similar to a component invocation), thus eliminating the need for a tl;dr I am pro |
For what it's worth, this was the original motivation for |
Right! Before ES6 and block-scoped I also really appreciate using analogies to other programming languages when designing and using Ember's templates. It's the right way to think about it, and goes a long way towards keeping the overall model small and simple. |
Hey everyone, this RFC was discussed at the last Core meeting and we decided to give it the green light, as the concerns raised during the FCP are addressed in the proposal. |
Rendered
This RFC is intended as a subset of #200.
Changelog
v2
let
with
deprecation to "Future Work"if-let
,let*
to "Future Work"