I've run into a strange problem and I'm not sure how to work around it. I have a list of items which I render in a list table with the ability to change the sort order of the items displayed.
Each row also has a div:
<button @onclick="Sort">Test</button>
<table>
@foreach (var item in Transactions)
{
<tr>
<td>
@item.Id
</td>
<td>
@item.Description
</td>
<td>
<div>
Hello World
</div>
</td>
</tr>
}
</table>
@code {
public void Sort()
{
Transactions = Transactions.OrderByDescending(x => x.GetType().GetProperty("Id").GetValue(x, null)).ToList();
}
}
When I run this, before I press the sort button I change the content of the first div in the first row from Hello world to anything else using element inspector in the browser console and then press the sort button.
The list is now displayed in reverse order as it should, but the first div in the first row still contains the modified content (when now it should be the last row div).
The above is a simplified representation of the problem, in my real app, the div is a component which contains displays a string variable internal to itself and which can change based on a user action within the component (Custom Select dropdown) and of course the same problem occurs.
How can I ensure the div for each row is actually tied to the order of the list items displayed?
** UPDATE **
I added the key attribute to the div but this just seems to reset the value back to what it was instead of preserving it:
<table>
@foreach (var item in listResponse.Transactions)
{
<tr>
<td>
@item.Id
</td>
<td>
@item.Description
</td>
<td>
<div @key=item.Id>
Hello World
</div>
</td>
</tr>
}
</table>
CodePudding user response:
The blazor way is the use @key see control-the-preservation-of-elements-and-components
@foreach (var item in Transactions)
{
<tr @key="item">
...
</tr>
}
you can also use css flex order, this directly controls the elements from css and will overide whatever blazor is doing, visually only!
also see codepen example
if you do want to use css I'd use a for loop as we can add the index manually ...
for (int i = 0; i < list.Count; i ) // Loop through List with for
{
<div style="order: @i">1</div>
}
.flex-container {
display: flex;
align-items: stretch;
background-color: #f1f1f1;
}
.flex-container>div {
background-color: DodgerBlue;
color: white;
width: 100px;
margin: 10px;
text-align: center;
line-height: 75px;
font-size: 30px;
}
<div >
<div style="order: 3">1</div>
<div style="order: 2">2</div>
<div style="order: 4">3</div>
<div style="order: 1">4</div>
</div>