Hi @kelvin, I think it’s important to consider the state here to realize what’s happening and how to fix it.
When you have this code:
@onChange={{action (mut annoViewer)}}
it’s the same as writing
@onChange={{action (mut this.annoViewer)}}
And actually you should probably use this.
explicitly, there’s even a lint rule for that, but that’s a side topic. Anyway, when you set this value you’re setting it on the backing class, either controller or component. This means you’re simply setting a boolean on your backing class. Makes sense. But when you are in the loop …
{{#each pictures as |pic|}}
...
{{#if this.annoViewer}}
{{#paper-card-content}}
{{else}}
...
{{/if}}
...
{{/each}}
you can think of it as just expanding what’s inside the loop a bunch of times, something like this:
...
{{#if this.annoViewer}}
{{#paper-card-content}}
{{else}}
...
{{/if}}
...
{{#if this.annoViewer}}
{{#paper-card-content}}
{{else}}
...
{{/if}}
...
{{#if this.annoViewer}}
{{#paper-card-content}}
{{else}}
...
{{/if}}
...
So now it’s easier to see what’s going on. Every single if
block is referencing the same backing class state, so they will all respond the same way.
There are a number of ways to solve this, and which direction you go depends on how you want it to behave. If you only want one picture expanded at a time you can stick with one backing class property and use an id instead of a boolean. The id would be the id of the “currently expanded” picture. Then each picture simply needs to check its id against the value, something like
{{#if (eq this.annoViewer pic.id}}
...
But if you want an arbitrary number of pictures to be expandable you have to store the state in some other way. You could abstract a “picture card” (e.g. if/else block) into a component, and let the component store its own expanded state (this would probably be my approach). Or you could store an array of picture ids and check if each picture id is in the array to know whether or not its expanded.