Selaa lähdekoodia

AccountPage layout and local storage functionality

master
Flo Smilari 4 vuotta sitten
vanhempi
commit
167cfa5acc
7 muutettua tiedostoa jossa 216 lisäystä ja 20 poistoa
  1. 12
    10
      App.razor
  2. 44
    10
      Pages/AccountPage.razor
  3. 1
    0
      Program.cs
  4. 32
    0
      Shared/UserData.cs
  5. 35
    0
      Shared/UserDataComponent.razor
  6. 72
    0
      Shared/UserDataProvider.cs
  7. 20
    0
      wwwroot/index.html

+ 12
- 10
App.razor Näytä tiedosto

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

+ 44
- 10
Pages/AccountPage.razor Näytä tiedosto

@page "/account" @page "/account"
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject UserDataProvider UserDataProvider
<h1>Counter</h1>
<div class="row px-3 h-100">
<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>
</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>
</div>
</div>
<div class="row no-gutters align-items-center w-100">
<div class="col-12">
<MatStringField Class="w-100" Label="Address" Outlined="true"></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"></MatStringField>
</div>
<div class="col-8" style="padding-left:0.5em">
<MatStringField Class="w-100" Label="City" Outlined="true"></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"></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"></MatStringField>
</div>
</div>
</div>
<div class="row no-gutters align-items-end justify-content-center w-100" style="padding-bottom:2em">
<MatButton Class="w-100" Raised="true" @onclick="SaveUserData">Speichern</MatButton>
</div>
</div>
<p>Current count: @currentCount</p>
<MatList>
<MatListItem>
<MatButton Raised="true" @onclick="IncrementCount">Click me!</MatButton>
</MatListItem>
</MatList>
@code { @code {
private int currentCount = 0;
private void IncrementCount() {
currentCount++;
async private void SaveUserData() {
await UserDataProvider.Save();
} }
[CascadingParameter]
public UserData State { get; set; }
} }

+ 1
- 0
Program.cs Näytä tiedosto

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddMatBlazor(); builder.Services.AddMatBlazor();
builder.Services.AddSingleton<AppState>(); builder.Services.AddSingleton<AppState>();
builder.Services.AddScoped<UserDataProvider>();
await builder.Build().RunAsync(); await builder.Build().RunAsync();
} }

+ 32
- 0
Shared/UserData.cs Näytä tiedosto

using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace CaritasPWA.Shared {
// The class that stores the user settings
public class UserData : INotifyPropertyChanged {
private string firstname;
private string lastname;
public string Firstname {
get => firstname;
set {
firstname = value;
RaisePropertyChanged();
}
}
public string Lastname {
get => lastname;
set {
lastname = value;
RaisePropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

+ 35
- 0
Shared/UserDataComponent.razor Näytä tiedosto

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

+ 72
- 0
Shared/UserDataProvider.cs Näytä tiedosto

using Microsoft.JSInterop;
using System;
using System.ComponentModel;
using System.Threading.Tasks;
namespace CaritasPWA.Shared {
public sealed class UserDataProvider {
private const string KeyName = "state";
private readonly IJSRuntime _jsRuntime;
private bool _initialized;
private UserData _data;
public event EventHandler Changed;
public bool AutoSave { get; set; } = true;
public UserDataProvider(IJSRuntime jsRuntime) {
_jsRuntime = jsRuntime;
}
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
if (!_initialized) {
// Create a reference to the current object, so the JS function can call the public method "OnStorageUpdated"
var reference = DotNetObjectReference.Create(this);
await _jsRuntime.InvokeVoidAsync("BlazorRegisterStorageEvent", reference);
_initialized = true;
}
// Read the JSON string that contains the data from the local storage
UserData result;
var str = await _jsRuntime.InvokeAsync<string>("BlazorGetLocalStorage", KeyName);
if (str != null) {
result = System.Text.Json.JsonSerializer.Deserialize<UserData>(str) ?? new UserData();
} else {
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;
}
public async Task Save() {
var json = System.Text.Json.JsonSerializer.Serialize(_data);
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) {
if (key == KeyName) {
// Reset the settings. The next call to Get will reload the data
_data = null;
Changed?.Invoke(this, EventArgs.Empty);
}
}
}
}

+ 20
- 0
wwwroot/index.html Näytä tiedosto

</head> </head>
<body> <body>
<app>Loading...</app> <app>Loading...</app>
<div id="blazor-error-ui"> <div id="blazor-error-ui">
</div> </div>
<script src="_framework/blazor.webassembly.js"></script> <script src="_framework/blazor.webassembly.js"></script>
<script>navigator.serviceWorker.register('service-worker.js');</script> <script>navigator.serviceWorker.register('service-worker.js');</script>
<script>
function BlazorSetLocalStorage(key, value) {
localStorage.setItem(key, value);
}
function BlazorGetLocalStorage(key) {
return localStorage.getItem(key);
}
function BlazorRegisterStorageEvent(component) {
window.addEventListener("storage", async e => {
await component.invokeMethodAsync("OnStorageUpdated", e.key);
});
}
</script>
</body> </body>
</html> </html>

Loading…
Peruuta
Tallenna