I’m having some trouble trying to create a UI feature within my Ember app.
What this feature entails is having a dynamically generated list of elements where, whenever the div element on line 13 is clicked, the FileThreads component related to that particular element can be seen. I’ve been having trouble figuring out how to do this in Ember, and for the moment the code will display every FileThreads component regardless of which div element is clicked.
My initial idea was to define this.id as id from the div element on line 13 in the Handlebar file and use this.id within the test getter to distinguish between the relevant FileThreads component and the other FileThreads. Of course, that’s not what the code in the test getter is doing, but I got too confused with what I was trying to do.
Thank you in advance.
I think you’re doing more work than necessary. For example with ember-truth-helpers you could change the template line 15 to something like:
{{#if (eq thread.id this.id)}}
...
{{/if}}
and get rid of the test
CP entirely.
Also, and this is unrelated, you should consider using a button instead of a div
for the “clickable” element. Semantic markup is important (especially for things like accessibility) and div
elements aren’t meant to be interactive. A button can always be styled however you want and screen readers would be able to understand what it is, vs a div which doesn’t tell a screen reader anything. There’s a template lint rule to enforce this too!
Typically the way I would handle something like this is the following (pared down for brevity):
// backing class
@tracked thingToShow = null;
@action hideThing() {
this.thingToShow = null;
}
// template
<ul> {{!-- or some other wrapper --}}
{{#each things as |thing|}}
<ThingItem @thing={{thing}} onClick={{fn (mut this.thingToShow)}} /> {{!-- or better yet use the set helper --}}
{{/each}}
{{#if this.thingToShow}}
<ThingDetail @thing={{this.thingToShow}} />
{{/if}}
</ul>
The only state that needs to be set on the backing class is the thing that needs to be shown in detail (if any). The “show thing” action can all be done in the template with the mut/set helper, and the decision about which “thing” to show is easy, it’s just whatever thing ref is set on the backing class. That said you can always do it by id or some other mechanism.
Does that all make sense? Hopefully I’m not ignoring some big part of your use case.
Have you considered accessibility with this? Clicking a non-interactive element breaks all accessibility, keyboard, focus, screen readers. How about some semantic HTML maybe using <details>
/<summery>
or possibly the hidden
attribute on the sub-lists? Might make any CSS animations you want easier too.