From eee849a64cac0545aa8c4700b65ab7b3060c0717 Mon Sep 17 00:00:00 2001 From: Yuriy Durov Date: Thu, 23 May 2024 14:42:19 +0400 Subject: [PATCH] State bugfixes --- .../ViewModels/CounterViewModel.cs | 3 ++- .../Components/ComponentBase{TViewModel}.cs | 1 + .../Components/ComponentStateContainer.razor.cs | 11 +++++++++++ .../Factory/ViewModelFactory.cs | 3 +++ src/BitzArt.Blazor.MVVM/Models/ViewModel.cs | 14 ++++++++++++++ .../Services/BlazorViewModelStateManager.cs | 12 +++++++++++- 6 files changed, 42 insertions(+), 2 deletions(-) diff --git a/sample/BitzArt.Blazor.MVVM.SampleApp/BitzArt.Blazor.MVVM.SampleApp.Client/ViewModels/CounterViewModel.cs b/sample/BitzArt.Blazor.MVVM.SampleApp/BitzArt.Blazor.MVVM.SampleApp.Client/ViewModels/CounterViewModel.cs index fdbc2e9..b5b34d7 100644 --- a/sample/BitzArt.Blazor.MVVM.SampleApp/BitzArt.Blazor.MVVM.SampleApp.Client/ViewModels/CounterViewModel.cs +++ b/sample/BitzArt.Blazor.MVVM.SampleApp/BitzArt.Blazor.MVVM.SampleApp.Client/ViewModels/CounterViewModel.cs @@ -19,8 +19,9 @@ public string NameOnPage } } - public override void InitializeState() + public override async Task InitializeStateAsync() { + await Task.Delay(1000); State.Text = $"Counter State initialized on: {renderingEnvironment}"; } diff --git a/src/BitzArt.Blazor.MVVM/Components/ComponentBase{TViewModel}.cs b/src/BitzArt.Blazor.MVVM/Components/ComponentBase{TViewModel}.cs index d658934..ab60a96 100644 --- a/src/BitzArt.Blazor.MVVM/Components/ComponentBase{TViewModel}.cs +++ b/src/BitzArt.Blazor.MVVM/Components/ComponentBase{TViewModel}.cs @@ -73,6 +73,7 @@ protected virtual async Task InitializeStateAsync() statefulViewModel.OnStateInitializedAsync?.Invoke(ViewModel); StateHasChanged(); + ViewModel.ComponentStateContainer?.NotifyStateChanged(); } protected virtual async Task RestoreStateAsync() diff --git a/src/BitzArt.Blazor.MVVM/Components/ComponentStateContainer.razor.cs b/src/BitzArt.Blazor.MVVM/Components/ComponentStateContainer.razor.cs index 0711016..0814bbd 100644 --- a/src/BitzArt.Blazor.MVVM/Components/ComponentStateContainer.razor.cs +++ b/src/BitzArt.Blazor.MVVM/Components/ComponentStateContainer.razor.cs @@ -17,6 +17,12 @@ public partial class ComponentStateContainer : ComponentBase [Parameter] public string StateElementKey { get; set; } = "state"; + protected override void OnInitialized() + { + base.OnInitialized(); + ViewModel.ComponentStateContainer = this; + } + protected override void BuildRenderTree(RenderTreeBuilder builder) { var stateElement = BuildStateElement(); @@ -35,4 +41,9 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) return $""; } + + public void NotifyStateChanged() + { + StateHasChanged(); + } } diff --git a/src/BitzArt.Blazor.MVVM/Factory/ViewModelFactory.cs b/src/BitzArt.Blazor.MVVM/Factory/ViewModelFactory.cs index 6717293..4ec321b 100644 --- a/src/BitzArt.Blazor.MVVM/Factory/ViewModelFactory.cs +++ b/src/BitzArt.Blazor.MVVM/Factory/ViewModelFactory.cs @@ -59,6 +59,9 @@ public ViewModel Create(IServiceProvider serviceProvider, Type viewModelType, Co var nestedSignature = new ComponentSignature(parent: signature); var injectedViewModel = Create(serviceProvider, injection.DependencyType, nestedSignature, parent: viewModel, affectedViewModels: affectedViewModels); injection.Property.SetValue(viewModel, injectedViewModel); + + viewModel.OnComponentStateContainerWasSet += (container) + => injectedViewModel.ComponentStateContainer = container; } else if (injection.IsParentViewModelInjection) diff --git a/src/BitzArt.Blazor.MVVM/Models/ViewModel.cs b/src/BitzArt.Blazor.MVVM/Models/ViewModel.cs index 55bf1a3..ea934c5 100644 --- a/src/BitzArt.Blazor.MVVM/Models/ViewModel.cs +++ b/src/BitzArt.Blazor.MVVM/Models/ViewModel.cs @@ -15,6 +15,20 @@ public abstract class ViewModel internal ComponentSignature Signature { get; set; } = null!; + private ComponentStateContainer? _componentStateContainer; + internal ComponentStateContainer? ComponentStateContainer + { + get => _componentStateContainer; + set + { + _componentStateContainer = value; + OnComponentStateContainerWasSet?.Invoke(value!); + } + } + + internal delegate void ComponentStateContainerWasSetHandler(ComponentStateContainer sender); + internal ComponentStateContainerWasSetHandler? OnComponentStateContainerWasSet { get; set; } + protected TViewModel CreateNestedViewModel() where TViewModel : ViewModel { diff --git a/src/BitzArt.Blazor.MVVM/Services/BlazorViewModelStateManager.cs b/src/BitzArt.Blazor.MVVM/Services/BlazorViewModelStateManager.cs index 4e2b1f7..2de9b24 100644 --- a/src/BitzArt.Blazor.MVVM/Services/BlazorViewModelStateManager.cs +++ b/src/BitzArt.Blazor.MVVM/Services/BlazorViewModelStateManager.cs @@ -1,5 +1,7 @@ +using System.Reflection; using System.Text.Json; using System.Text.Json.Nodes; +using System.Text.Json.Serialization; namespace BitzArt.Blazor.MVVM; @@ -27,8 +29,16 @@ internal class BlazorViewModelStateManager(IViewModelFactory viewModelFactory) if (viewModel is IStatefulViewModel statefulViewModel && statefulViewModel.State.IsInitialized) { - foreach (var property in statefulViewModel.StateType.GetProperties()) + var nodeJson = (JsonObject)JsonSerializer.SerializeToNode(statefulViewModel.State, statefulViewModel.State.GetType(), StateJsonOptionsProvider.Options)!; + foreach (var node in nodeJson) state.Add(node.Key, node.Value); + + //var nodeState = JsonSerializer.Deserialize>(json, StateJsonOptionsProvider.Options)!; + //foreach (var item in nodeState) state.Add(item.Key, item.Value); + + /*foreach (var property in statefulViewModel.StateType.GetProperties()) + { state.Add(property.Name, property.GetValue(statefulViewModel.State)); + }*/ } foreach (var injection in injectionMap.Injections.Where(x => x.IsNestedViewModelInjection))