Skip to content

Commit

Permalink
Allow fields as component state
Browse files Browse the repository at this point in the history
  • Loading branch information
YuriyDurov committed Sep 15, 2024
1 parent 0408ad8 commit e419c0c
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<h4>@Name</h4>

<p role="status">Current count: @Count</p>
<p role="status">Current count: @_count</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ public partial class Counter : PersistentComponentBase
public string? Description { get; set; }

[ComponentState]
public int Count { get; private set; } = 0;
private int _count = 0;

[ComponentState]
public string InfoText { get; set; } = string.Empty;
private string InfoText = string.Empty;

protected override async Task InitializeStateAsync()
{
Expand All @@ -25,7 +25,7 @@ protected override async Task InitializeStateAsync()

private void IncrementCount(object? state)
{
Count++;
_count++;
StateHasChanged();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@

<PageTitle>Counter</PageTitle>

<p>Current rendermode: @RendererInfo.Name</p>

@if (!RendererInfo.IsInteractive)
{
<p>Waiting for interactivity..</p>
}

<Counter Name="Counter 1"
Description="This counter is initialized while pre-rendering"
Description="This counter is rendered in all render modes"
StateId="Counter1"/>

<Counter Name="Counter 2"
Description="This counter is initialized while pre-rendering"
StateId="Counter2" />
@if (RendererInfo.IsInteractive)
{
<Counter Name="Counter 2"
Description="This counter is only rendered in interactive render modes"
StateId="Counter2" />
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/// <summary>
/// Marks a property to be persisted between rendering environments.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class ComponentStateAttribute : Attribute
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ internal class PersistentComponentStateInfo(Type componentType)
public Type ComponentType { get; set; } = componentType;

public IEnumerable<StatePropertyInfo> StateProperties { get; set; }
= componentType.GetProperties()
= componentType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(p => p.GetCustomAttribute<ComponentStateAttribute>() != null)
.Select(p => new StatePropertyInfo(componentType, p))
.ToList();

public IEnumerable<StateFieldInfo> StateFields { get; set; }
= componentType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
.Where(f => f.GetCustomAttribute<ComponentStateAttribute>() != null)
.Select(f => new StateFieldInfo(componentType, f))
.ToList();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Reflection;

namespace BitzArt.Blazor.State;

internal class StateFieldInfo(Type componentType, FieldInfo fieldInfo)
{
public Type ComponentType { get; set; } = componentType;
public FieldInfo FieldInfo { get; set; } = fieldInfo;
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,17 @@ protected void RestoreComponentState(JsonObject state)
var deserializedValue = value.Deserialize(propertyInfo.PropertyType, serializerOptions);
propertyInfo.SetValue(PersistentComponent, deserializedValue);
}

foreach (var field in stateInfo.StateFields)
{
var fieldInfo = field.FieldInfo;
var value = state[fieldInfo.Name];

if (value is null) continue;

var deserializedValue = value.Deserialize(fieldInfo.FieldType, serializerOptions);
fieldInfo.SetValue(PersistentComponent, deserializedValue);
}
}

private IEnumerable<string> GetComponentLocation(PersistentComponentBase component)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ internal class PersistentComponentStateComposer(
node.Add(property.PropertyInfo.Name, serializedValue);
}

// Serialize descendants
// Serialize fields
foreach (var field in stateInfo.StateFields)
{
var value = field.FieldInfo.GetValue(component);
var serializedValue = JsonSerializer.SerializeToNode(
value, field.FieldInfo.FieldType, serializerOptions);

node.Add(field.FieldInfo.Name, serializedValue);
}

// Proceed to descendants
foreach (var descendant in component.StateDescendants)
{
var descendantNode = SerializeStateNode(descendant);
Expand Down

0 comments on commit e419c0c

Please sign in to comment.