Facepunch / sbox-issues

175 stars 12 forks source link

@key Attribute for Razor #4103

Open rndtrash opened 11 months ago

rndtrash commented 11 months ago

For?

S&Box

What can't you do?

The @key attribute allows the developer to control the way the panel is re-rendered. It lets the renderer know which panels should be deleted or changed based on the @key value. A similar attribute exists in many JS and TS frontend frameworks.

For example:

@foreach (var el in elements)
{
 <SomePanel @Element=@el/>
}

In this example, if the first element is removed from the elements list, then all the panels would be rendered again with the different properties, resulting in a loss of state.

How would you like it to work?

Just like in Blazor.

What have you tried?

I have tried adding the @key attribute to any of the panels. s&box throws an error saying there is no such attribute.

Additional context

Official Microsoft Docs: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-7.0#key Official Microsoft @key Tutorial: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/element-component-model-relationships?view=aspnetcore-7.0

MrBrax commented 11 months ago

gosh i miss this from vue

fluffybagel commented 8 months ago

This is crucial for things like a connected player list, where the amount of elements might change frequently

xezno commented 8 months ago

What is the difference between this and just using BuildHash

MrBrax commented 8 months ago

elements in a list might get confused since the contents of the list gets changed around but not the id of the individual items, you get duplicate data

rndtrash commented 8 months ago

What is the difference between this and just using BuildHash

@xezno As I said in the first comment, the @key attribute controls the lifecycle of a panel. Say, I want to render a list of players, and it's ordered alphabetically.

Andy
Bob
John

Each item has a panel assigned to it. If a player called "Alice" joins the game, then the following happens:

panel Andy gets it's value replaced to Alice
Bob -> Andy
John -> Bob
and John gets a new panel

Needless to say, this is suboptimal. With a @key attribute, we can assign each panel a unique key, in this case, the key would be a Steam ID or the name itself. That way, Alice would get a new panel, while the rest of the panels would remain unchanged.

You can read more on that topic in this official Microsoft tutorial: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/element-component-model-relationships?view=aspnetcore-7.0

fluffybagel commented 8 months ago

I was able to find an issue with rendering lists with svg or svgpanel elements that I suspect may be related to this issue. See the following list of players: image When players are added to the list, they are rendered correctly. When you remove players from the list, the svgs get scrambled, even though the other elements are rendered correctly: image When looking at the UI Panels, the svgpanel is showing the correct file src, but the svg rendered is incorrect: image