[RFC #338] Implement new template helpers#17177
[RFC #338] Implement new template helpers#17177cibernox wants to merge 21 commits intoemberjs:masterfrom
Conversation
- [x] Implement `{{eq}}` helper
- [ ] Implement `{{not}}` helper
- [ ] Implement `{{and}}` helper
- [ ] Implement `{{or}}` helper
- [ ] Implement `{{gt}}` helper
- [ ] Implement `{{gt3}}` helper
- [ ] Implement `{{lt}}` helper
- [ ] Implement `{{lte}}` helper
| this.render(`{{gt left right}}`, { | ||
| left: undefined, | ||
| get right() { | ||
| debugger; |
There was a problem hiding this comment.
@rwjblue Any guidance on how to define a getter or a CP to verify that its value is not eagerly pulled by the helper? Seems that right now the keys of this object are eagerly accessed by Object.assign by the setup of the test itself.
There was a problem hiding this comment.
Instead of rendering gt directly render a component whose own template uses gt, then have that component have left and right CP’s that you can track when they are evaluated
9703584 to
c21356b
Compare
It has lazy evaluation of the second argument, so it doesn't even get read if the first argument is already undefined. For now without an option to coerce strings to numbers.
c21356b to
4fecacb
Compare
|
@rwjblue Tests are failing because of missing documentation, however I've documented every helper, so I'm not sure what I'm missing. |
| @public | ||
| @method and | ||
| @for Ember.Templates.helpers | ||
| @since 2.7.0 |
There was a problem hiding this comment.
Master is 2.7, am I wrong? 2.6 maybe?
Off the top of my head, I’d say no.... |
rwjblue
left a comment
There was a problem hiding this comment.
Looking really good here, only major thing that I see is that it needs feature flagging...
| const BUILTINS_HELPERS = { | ||
| if: inlineIf, | ||
| action, | ||
| and, |
There was a problem hiding this comment.
Adding to the BUILTINS_HELPERS array needs to be guarded by feature flags
|
I added a feature flag. It's enabled by default. |
| let last: any = true; | ||
| for (let i = 0; i < references.length; i++) { | ||
| last = references[i].value(); | ||
| if (!last) { |
There was a problem hiding this comment.
@chancancode - Should we consider [] as falsey here? In general, in template land I think we do right?
There was a problem hiding this comment.
yeah, I think we do.
ember.js/packages/@ember/-internals/glimmer/lib/utils/to-bool.ts
Lines 4 to 10 in 1b7e613
I bigger question is should we support proxies, I completely forgot about that. I think that needed to be discussed and clarified in the RFC 🤧
There was a problem hiding this comment.
That is surprising. I was expecting and/or helpers to behave just like && / II. Why this deviation from standard JS behaviour?
There was a problem hiding this comment.
{{#each}} is designed to display lists, and seems normal that it has special behavior for empty lists, but and and or are not for lists, so I don't see why the behavior of {{each}} should influence them and make them behave different than && and ||
On top of that, this is not how ember-truth-helpers behave. I'm not saying that we can't deviate from what e-t-h if there is a good reason, but it would be nice not to.
There was a problem hiding this comment.
Well it really isn't about each, {{#if someEmptyArray}}{{else}}{{/if}} will render the falsey branch. I think it is very confusing to have if behave differently than eq/not.
There was a problem hiding this comment.
It works the same way for...
...and with, let etc. I think the bottom line is it would be pretty surprising if {{else}} doesn't work consistently in the control flow things in the "language".
So now what if you refactor from the first example into...
...what should this do?
There was a problem hiding this comment.
I think it is probably important for the "language" to have one boolean semantics, and for better or for worse empty arrays are falsey everywhere else.
| return false; | ||
| } | ||
| let right = references[1].value(); | ||
| if (right === undefined) { |
There was a problem hiding this comment.
Does this satisfy a specific edge case? I would have imagined that the following would have been enough:
return left > right;There was a problem hiding this comment.
I tried, but typescript doesn't like comparing things with null or undefined.
| return false; | ||
| } | ||
| if (right === null) { | ||
| return left >= 0; |
There was a problem hiding this comment.
This seems odd to me, why do we need to extra logic (vs just using the final return left >= right)?
There was a problem hiding this comment.
Same reason. Typescript doesn't ket me compare things with undefined or null. How can we silence that?
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
Co-Authored-By: cibernox <miguel.camba@gmail.com>
|
Closing this as it would have to be reworked |
|
For reference, the original RFC has been superseded. See emberjs/rfcs#388 (comment) for full details. |
{{eq}}helper{{not-eq}}helper{{not}}helper{{and}}helper{{or}}helper{{gt}}helper{{gte}}helper{{lt}}helper{{lte}}helperOpen questions:
{{gt}},{{gte}},{{lt}}and{{lte}}fromember-truth-helperstake a named argumentforceNumber=trueto transform input arguments to numbers. Do we want to replicate those too?