The following code snippet does exactly what I expect, which is to provide a list of 3 items that expands to show the numeral for the written number when clicked. My question is whether a Dictionary is the proper way to track the state?
Do I really have to maintain a copy of the state on this page, or is there a way to bind the click event to directly modify the value of the property on the component rather than a local copy of the status which is bound to the components value?
<div class="row">
<div class="col">
<ul>
@if(Items != null)
{
foreach(var kvp in Items)
{
<li @key="kvp.Key" @onclick="@(e => Toggle(kvp.Key))">@kvp.Key <CollapsibleRow @bind-Expanded="expanded[kvp.Key]">@kvp.Value</CollapsibleRow></li>
}
}
</ul>
</div>
</div>
@code {
Dictionary<string, bool> expanded = Items.Select(o => new KeyValuePair<string, bool>(o.Key, false)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
void Toggle(string key)
{
expanded[key] = !expanded[key];
}
static Dictionary<string, string> Items = new()
{
{ "One", "1" },
{ "Two", "2" },
{ "Three", "3" }
};
}
3
Answers
Here is the code I ended up with that gets rid of the "middle man", so to speak, so that I can directly call the Toggle method on the component rather than having to rely on a property binding. Although not shown here, this also reduces the amount of code necessary in the component itself now that it doesn't need to expose a parameter.
In this case I would move away from the Dictionary, and use a view model instead, so that the expanded tracking is held with the object itself. I may have mixed up where you have used the number and the name of the number, but hopefully you get the idea.
You need to maintain state if you wish to preserve the state across page changes. If not, you can maintain state internally.
Here’s a Bootstrap accordion version of your code where the state is maintained by each
AccordionItem
.Accordion
AccordionItem
Home