瀏覽代碼

AccountPage layout and local storage functionality

 - load on show page and save via button
master
Flo Smilari 4 年之前
父節點
當前提交
63ec20be38
共有 5 個檔案被更改,包括 50 行新增85 行删除
  1. 10
    12
      App.razor
  2. 25
    11
      Pages/AccountPage.razor
  3. 8
    14
      Shared/UserData.cs
  4. 0
    35
      Shared/UserDataComponent.razor
  5. 7
    13
      Shared/UserDataProvider.cs

+ 10
- 12
App.razor 查看文件

<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>

+ 25
- 11
Pages/AccountPage.razor 查看文件

<div class="row no-gutters align-items-start w-100"> <div class="row no-gutters align-items-start w-100">
<div class="row no-gutters w-100" style="padding-top:2em"> <div class="row no-gutters w-100" style="padding-top:2em">
<div class="col-6" style="padding-right:0.5em"> <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>
<div class="col-6" style="padding-left:0.5em"> <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> </div>
<div class="row no-gutters align-items-center w-100"> <div class="row no-gutters align-items-center w-100">
<div class="col-12"> <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> </div>
<div class="row no-gutters align-items-center w-100"> <div class="row no-gutters align-items-center w-100">
<div class="col-4" style="padding-right:0.5em"> <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>
<div class="col-8" style="padding-left:0.5em"> <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> </div>
<div class="row no-gutters align-items-center w-100"> <div class="row no-gutters align-items-center w-100">
<div class="col-12"> <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> </div>
<div class="row no-gutters align-items-center w-100"> <div class="row no-gutters align-items-center w-100">
<div class="col-12"> <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> </div>
</div> </div>
@code { @code {
async private void SaveUserData() {
protected async override void OnInitialized() {
await GetUserData();
}
private async void SaveUserData() {
await UserDataProvider.Save(); 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;
}
}

+ 8
- 14
Shared/UserData.cs 查看文件

namespace CaritasPWA.Shared { namespace CaritasPWA.Shared {
// The class that stores the user settings // The class that stores the user settings
public class UserData : INotifyPropertyChanged {
public class UserData {
private string firstname; private string firstname;
private string lastname; private string lastname;
private string address; private string address;
private string email; 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; } }
} }
} }

+ 0
- 35
Shared/UserDataComponent.razor 查看文件

@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();
}
}

+ 7
- 13
Shared/UserDataProvider.cs 查看文件

namespace CaritasPWA.Shared { namespace CaritasPWA.Shared {
public sealed class UserDataProvider { public sealed class UserDataProvider {
private const string KeyName = "state";
private const string KeyName = "account";
private readonly IJSRuntime _jsRuntime; private readonly IJSRuntime _jsRuntime;
private bool _initialized; private bool _initialized;
private UserData _data;
private UserData _data = new UserData();
public UserData Data {
get => _data;
set => _data = value;
}
public event EventHandler Changed; public event EventHandler Changed;
public bool AutoSave { get; set; } = true; public bool AutoSave { get; set; } = true;
} }
public async ValueTask<UserData> Get() { public async ValueTask<UserData> Get() {
if (_data != null)
return _data;
// Register the Storage event handler. This handler calls OnStorageUpdated when the storage changed. // 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 // This way, you can reload the settings when another instance of the application (tab / window) save the settings
result = new UserData(); 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; _data = result;
return result; return result;
} }
await _jsRuntime.InvokeVoidAsync("BlazorSetLocalStorage", KeyName, json); 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 // This method is called from BlazorRegisterStorageEvent when the storage changed
[JSInvokable] [JSInvokable]
public void OnStorageUpdated(string key) { public void OnStorageUpdated(string key) {

Loading…
取消
儲存