-
-
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
maybe, maybe not better on syntax - this RFC accidentally found some decision trees around when to use {{on}} vs on* #1007
Conversation
what do we actually get with the new syntax? |
Naw, just on
Idk, the main thing is event modifiers
Shorter event binding, event modifiers, having builtin event binding look different from userspace modifiers, potentially some perf for cleanup, as usage is more constrained, so we don't need to worry about teardown |
Feels like a lot of work throughout the ecosystem for little gain. Whole new syntax, would need guides, linting updates.. I like that |
I see it as a benefit of Ember that even basic functionality like Keeping it aligned with the primitives also eases migration story. No one expects |
Counterpoint (to myself) svelte is getting rid of this syntax in favor of normal 'onclick' , 'onkeypress', https://svelte-5-preview.vercel.app/docs/event-handlers#why-the-change And we can already use those, which i forgot about |
It's easy to teach new Ember devs the The proposed syntax will introduce a new Emberism to memorize, and I don't think it adds enough value to justify its expense on the cognitive load of Ember learners. The native The existing
The proposed syntactic sugar for adding the With all that said, I do share the concern at the root of the proposal. While template imports are fantastic for the node processes living in the build system, they're a pain for humans authoring components. It's hard to remember the 20 different locations that common things need to be imported from. I consult this reference almost daily because it just doesn't ever seem to click if one thing comes from Many authors also carry Taken in sum, the top of a gjs/gts starts to look like the top of a java file; and without a strong intellisense system to hand wave the problem away. I do think this is an adoption hurdle for Polaris, and reducing the cognitive burden would be a boon for Ember. I'd prefer a holistic approach to this problem rather than a hyperfocus on each specific template import statement. |
I pretty much agree with what everyone has written.
I would like to not have to import the built ins, it makes sense for me to import my user land code but I don't see why things like |
Sorry but i don't like the just text here
<button {{on 'click' itsClearThatThisIsAFunctionCall}} id="just-html">Do Something</button>
<span class="text">{{ aDynamicProperty }}</span> So even we just use the native js event syntax I would go more for transforming the native js events behind the scenes to the Before:
<button {{on 'click' increment}}>Increment</button>
After:
<button onclick={{increment}}>Increment</button> |
The Additionally, I see it as one of the major problems of Glimmer template syntax that it is unclear if it is an HTML attribute property. This currently depends on logic implementing in the Glimmer VM as far as I remember. We should not make that more complex by introducing more properties, which look like attributes but being handled as properties by the Glimmer VM. |
Thanks for all the feedback, based on all this, I've opened:
|
Maybe I'm missing something but that demo does not seem to show that you could use We could accept that trade-off for sure. Especially if it has a noticeable performance benefit. Likely primarily an issue for upgrade path and less for new code. |
ah, that's not how I interpreted "it can be only set once."
in this demo, that would have indeterminate behavior cross-browser, because the order of these specific event handlers needs to be, 1. increase the incrementBy, then 2., do the other handler. it should only be recommended to have multiple event handlers listening to the same event if the event handlers are totally independent in behavior and don't intend to cause the other handlers to behave differently (which is what's happening in my demo 😅 )
yeah, I think what I'm trying to narrow in on, is a sort of decision tree for when to use which thing: stateDiagram-v2
state "use onclick" as useOnclick
state "use {{on}}" as useOn
state "need cleanup" as cleanup
state "need conditional {{on}}" as cond
state "need multiple {{on}} the same event name" as multiple
state "handlers are independent" as indMultiple
state "combine the handlers to make serial" as serial
[*] --> cleanup
cleanup --> cond: no
cleanup --> useOn: yes
cond --> useOn: yes
cond --> multiple: no
multiple --> indMultiple: yes
multiple --> useOnclick: no
indMultiple --> serial: no
indMultiple --> useOn: yes
serial --> useOnclick
|
@NullVoxPopuli seems it may be compiler feature - if |
@lifeart yeah, I like that idea -- we could improve the performance of everyone's apps with a minor update with no change to anyone's code. and compiler changes like that don't need an RFC, because the wireformat is totally private to ember users |
@NullVoxPopuli seems main performance benefit gained not from attribute usage, it depends on do we have destructor or not. And generally
|
I agree completely with @evoactivity' s comment here, and want to add that microsyntaxes are hard to remember. |
Are there other use cases where this syntax could be used ? |
Do I understand correctly that performance benefit is gained from omitting
I don't think that's true. Destructor is critical if the modifier is applied conditionally. Even though that's not that often needed, it's a proper usage. |
not really, it was only meant for
yes, see the decision tree here: #1007 (comment)
static case is more common than conditional case. I personally cannot be ok with "proper" meaning 'less performant' 🙃 (hence decision tree! 🥳) |
That decision tree is only working for It sounds as if modifiers need the capability to optionally skip destructor if element is destroyed in the same render cycle. One of the many performance related features still missing for modifiers... |
What gap do you see as remaining?
If an element is destroyed, we don't need to worry about cleanup (with (for on, specifically) The case where we worry about cleanup is in dynamic modifiers. For all other modifiers, such as using the resize observer service, cleanup is very important)
yeah having more features in modifiers is nice - but is unrelated to how we use modifiers (in any syntax!). The feature I think we can implement today without any RFC or worry about public API is @lifeart's suggestion, but it is specifically about optimizing DOM cleanup (needed when navigating away from a page). The feature you want, (and I see you linked from the style-modifier repo), is a pre-paint timing, and that would be amazing, but requires manager changes. |
|
Why not have folks do: <div style="css here {{if cond 'other CSS'}}">
</div> or <div class="foo {{if cond 'bar'}}">
</div>
<style>
.foo {
&.bar {
}
}
</style> |
imo: the compiler opt isn't worth it for the additional complication and confusion it can lead to around event ordering and cleanup. Events added by a modifier/modifier syntax should all agree on what event delegation timing they have. |
Very intriguing. – Why teach to use a modifier when there is support by HTML natively? As we write in the very beginning of our guides:
function hello() {
alert('hello')
}
<template>
<button onclick={{hello}}>Hello</button>
</template>
// Only primitive values (see `AttrValue` in `@glint/template`) are assignable as HTML attributes.
// If you want to set an event listener, consider using the `{{on}}` modifier instead.
// Type 'void' is not assignable to type 'AttrValue'.glint(2322) |
I think this is correct. Because we teach that |
I think this is an oversight, tbh |
so after talking with a few people it seems the use case for |
Propose better
on
syntaxRendered
Alternative to RFC#997
Summary
This pull request is proposing a new RFC.
To succeed, it will need to pass into the Exploring Stage), followed by the Accepted Stage.
A Proposed or Exploring RFC may also move to the Closed Stage if it is withdrawn by the author or if it is rejected by the Ember team. This requires an "FCP to Close" period.
An FCP is required before merging this PR to advance to Accepted.
Upon merging this PR, automation will open a draft PR for this RFC to move to the Ready for Released Stage.
Exploring Stage Description
This stage is entered when the Ember team believes the concept described in the RFC should be pursued, but the RFC may still need some more work, discussion, answers to open questions, and/or a champion before it can move to the next stage.
An RFC is moved into Exploring with consensus of the relevant teams. The relevant team expects to spend time helping to refine the proposal. The RFC remains a PR and will have an
Exploring
label applied.An Exploring RFC that is successfully completed can move to Accepted with an FCP is required as in the existing process. It may also be moved to Closed with an FCP.
Accepted Stage Description
To move into the "accepted stage" the RFC must have complete prose and have successfully passed through an "FCP to Accept" period in which the community has weighed in and consensus has been achieved on the direction. The relevant teams believe that the proposal is well-specified and ready for implementation. The RFC has a champion within one of the relevant teams.
If there are unanswered questions, we have outlined them and expect that they will be answered before Ready for Release.
When the RFC is accepted, the PR will be merged, and automation will open a new PR to move the RFC to the Ready for Release stage. That PR should be used to track implementation progress and gain consensus to move to the next stage.
Checklist to move to Exploring
S-Proposed
is removed from the PR and the labelS-Exploring
is added.Checklist to move to Accepted
Final Comment Period
label has been added to start the FCP