- load on show page and save via buttonmaster
| @@ -1,12 +1,10 @@ | |||
| <UserDataComponent> | |||
| <Router AppAssembly="@typeof(Program).Assembly"> | |||
| <Found Context="routeData"> | |||
| <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> | |||
| </Found> | |||
| <NotFound> | |||
| <LayoutView Layout="@typeof(MainLayout)"> | |||
| <p>Sorry, there's nothing at this address.</p> | |||
| </LayoutView> | |||
| </NotFound> | |||
| </Router> | |||
| </UserDataComponent> | |||
| <Router AppAssembly="@typeof(Program).Assembly"> | |||
| <Found Context="routeData"> | |||
| <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" /> | |||
| </Found> | |||
| <NotFound> | |||
| <LayoutView Layout="@typeof(MainLayout)"> | |||
| <p>Sorry, there's nothing at this address.</p> | |||
| </LayoutView> | |||
| </NotFound> | |||
| </Router> | |||
| @@ -6,33 +6,33 @@ | |||
| <div class="row no-gutters align-items-start w-100"> | |||
| <div class="row no-gutters w-100" style="padding-top:2em"> | |||
| <div class="col-6" style="padding-right:0.5em"> | |||
| <MatStringField Class="w-100" Label="Firstname" Outlined="true" type="text" @bind-Value="@State.Firstname"></MatStringField> | |||
| <MatStringField Class="w-100" Label="Firstname" Outlined="true" type="text" @bind-Value="@Account.Firstname"></MatStringField> | |||
| </div> | |||
| <div class="col-6" style="padding-left:0.5em"> | |||
| <MatStringField Class="w-100" Label="Lastname" Outlined="true" type="text" @bind-Value="@State.Lastname"></MatStringField> | |||
| <MatStringField Class="w-100" Label="Lastname" Outlined="true" type="text" @bind-Value="@Account.Lastname"></MatStringField> | |||
| </div> | |||
| </div> | |||
| <div class="row no-gutters align-items-center w-100"> | |||
| <div class="col-12"> | |||
| <MatStringField Class="w-100" Label="Address" Outlined="true" type="text" @bind-Value="@State.Address"></MatStringField> | |||
| <MatStringField Class="w-100" Label="Address" Outlined="true" type="text" @bind-Value="@Account.Address"></MatStringField> | |||
| </div> | |||
| </div> | |||
| <div class="row no-gutters align-items-center w-100"> | |||
| <div class="col-4" style="padding-right:0.5em"> | |||
| <MatStringField Class="w-100" Label="Zip" Outlined="true" type="text" @bind-Value="@State.Zip"></MatStringField> | |||
| <MatStringField Class="w-100" Label="Zip" Outlined="true" type="text" @bind-Value="@Account.Zip"></MatStringField> | |||
| </div> | |||
| <div class="col-8" style="padding-left:0.5em"> | |||
| <MatStringField Class="w-100" Label="City" Outlined="true" type="text" @bind-Value="@State.City"></MatStringField> | |||
| <MatStringField Class="w-100" Label="City" Outlined="true" type="text" @bind-Value="@Account.City"></MatStringField> | |||
| </div> | |||
| </div> | |||
| <div class="row no-gutters align-items-center w-100"> | |||
| <div class="col-12"> | |||
| <MatStringField Class="w-100" Label="Phone" Outlined="true" type="text" @bind-Value="@State.Phone"></MatStringField> | |||
| <MatStringField Class="w-100" Label="Phone" Outlined="true" type="text" @bind-Value="@Account.Phone"></MatStringField> | |||
| </div> | |||
| </div> | |||
| <div class="row no-gutters align-items-center w-100"> | |||
| <div class="col-12"> | |||
| <MatStringField Class="w-100" Label="E-Mail" Outlined="true" type="text" @bind-Value="@State.Email"></MatStringField> | |||
| <MatStringField Class="w-100" Label="E-Mail" Outlined="true" type="text" @bind-Value="@Account.Email"></MatStringField> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -46,11 +46,25 @@ | |||
| @code { | |||
| async private void SaveUserData() { | |||
| protected async override void OnInitialized() { | |||
| await GetUserData(); | |||
| } | |||
| private async void SaveUserData() { | |||
| await UserDataProvider.Save(); | |||
| } | |||
| [CascadingParameter] | |||
| public UserData State { get; set; } | |||
| } | |||
| private async Task GetUserData() { | |||
| await InvokeAsync(async () => { | |||
| await UserDataProvider.Get(); | |||
| StateHasChanged(); | |||
| }); | |||
| } | |||
| private UserData Account { | |||
| get => UserDataProvider.Data; | |||
| } | |||
| } | |||
| @@ -3,7 +3,7 @@ using System.Runtime.CompilerServices; | |||
| namespace CaritasPWA.Shared { | |||
| // The class that stores the user settings | |||
| public class UserData : INotifyPropertyChanged { | |||
| public class UserData { | |||
| private string firstname; | |||
| private string lastname; | |||
| private string address; | |||
| @@ -13,18 +13,12 @@ namespace CaritasPWA.Shared { | |||
| private string email; | |||
| public string Firstname { get => firstname; set { firstname = value; RaisePropertyChanged(); } } | |||
| public string Lastname { get => lastname; set { lastname = value; RaisePropertyChanged(); } } | |||
| public string Email { get => email; set { email = value; RaisePropertyChanged(); } } | |||
| public string Address { get => address; set { address = value; RaisePropertyChanged(); }} | |||
| public string Zip { get => zip; set { zip = value; RaisePropertyChanged(); } } | |||
| public string City { get => city; set { city = value; RaisePropertyChanged(); } } | |||
| public string Phone { get => phone; set { phone = value; RaisePropertyChanged(); } } | |||
| public event PropertyChangedEventHandler PropertyChanged; | |||
| private void RaisePropertyChanged([CallerMemberName] string propertyName = null) { | |||
| PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); | |||
| } | |||
| public string Firstname { get => firstname; set { firstname = value; } } | |||
| public string Lastname { get => lastname; set { lastname = value; } } | |||
| public string Address { get => address; set { address = value; } } | |||
| public string Zip { get => zip; set { zip = value; } } | |||
| public string City { get => city; set { city = value; } } | |||
| public string Phone { get => phone; set { phone = value; } } | |||
| public string Email { get => email; set { email = value; } } | |||
| } | |||
| } | |||
| @@ -1,35 +0,0 @@ | |||
| @inject UserDataProvider UserDataProvider | |||
| @implements IDisposable | |||
| @if (state == null) { | |||
| <p>loading...</p> | |||
| } else { | |||
| <CascadingValue Value="@state" IsFixed="false">@ChildContent</CascadingValue> | |||
| } | |||
| @code{ | |||
| private UserData state = null; | |||
| [Parameter] | |||
| public RenderFragment ChildContent { get; set; } | |||
| protected override async Task OnInitializedAsync() { | |||
| UserDataProvider.Changed += UserDataChanged; | |||
| await Refresh(); | |||
| } | |||
| public void Dispose() { | |||
| UserDataProvider.Changed -= UserDataChanged; | |||
| } | |||
| private async void UserDataChanged(object sender, EventArgs e) { | |||
| await InvokeAsync(async () => { | |||
| await Refresh(); | |||
| StateHasChanged(); | |||
| }); | |||
| } | |||
| private async Task Refresh() { | |||
| state = await UserDataProvider.Get(); | |||
| } | |||
| } | |||
| @@ -5,12 +5,17 @@ using System.Threading.Tasks; | |||
| namespace CaritasPWA.Shared { | |||
| public sealed class UserDataProvider { | |||
| private const string KeyName = "state"; | |||
| private const string KeyName = "account"; | |||
| private readonly IJSRuntime _jsRuntime; | |||
| private bool _initialized; | |||
| private UserData _data; | |||
| private UserData _data = new UserData(); | |||
| public UserData Data { | |||
| get => _data; | |||
| set => _data = value; | |||
| } | |||
| public event EventHandler Changed; | |||
| public bool AutoSave { get; set; } = true; | |||
| @@ -20,8 +25,6 @@ namespace CaritasPWA.Shared { | |||
| } | |||
| public async ValueTask<UserData> Get() { | |||
| if (_data != null) | |||
| return _data; | |||
| // Register the Storage event handler. This handler calls OnStorageUpdated when the storage changed. | |||
| // This way, you can reload the settings when another instance of the application (tab / window) save the settings | |||
| @@ -41,8 +44,6 @@ namespace CaritasPWA.Shared { | |||
| result = new UserData(); | |||
| } | |||
| // Register the OnPropertyChanged event, so it automatically persists the settings as soon as a value is changed | |||
| result.PropertyChanged += OnPropertyChanged; | |||
| _data = result; | |||
| return result; | |||
| } | |||
| @@ -52,13 +53,6 @@ namespace CaritasPWA.Shared { | |||
| await _jsRuntime.InvokeVoidAsync("BlazorSetLocalStorage", KeyName, json); | |||
| } | |||
| // Automatically persist the settings when a property changed | |||
| private async void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { | |||
| if (AutoSave) { | |||
| await Save(); | |||
| } | |||
| } | |||
| // This method is called from BlazorRegisterStorageEvent when the storage changed | |||
| [JSInvokable] | |||
| public void OnStorageUpdated(string key) { | |||