实现多语言切换
This commit is contained in:
82
Atomx.Admin/Atomx.Admin.Client/Components/LangSelector.razor
Normal file
82
Atomx.Admin/Atomx.Admin.Client/Components/LangSelector.razor
Normal file
@@ -0,0 +1,82 @@
|
||||
@inject ILocalizationProvider LocalizationProvider
|
||||
@inject NavigationManager Navigation
|
||||
@inject IJSRuntime JS
|
||||
|
||||
<select @onchange="OnChange" value="@selected">
|
||||
@foreach (var item in options)
|
||||
{
|
||||
<option value="@item.Key">@item.Value</option>
|
||||
}
|
||||
</select>
|
||||
|
||||
@code {
|
||||
private string selected = "zh";
|
||||
|
||||
private readonly Dictionary<string, string> options = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "zh", "<22><><EFBFBD><EFBFBD>" },
|
||||
{ "en", "English" }
|
||||
};
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var current = LocalizationProvider.CurrentCulture;
|
||||
var mapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "zh", "zh-Hans" },
|
||||
{ "en", "en-US" }
|
||||
};
|
||||
var found = mapping.FirstOrDefault(kv => string.Equals(kv.Value, current, StringComparison.OrdinalIgnoreCase)).Key;
|
||||
if (!string.IsNullOrEmpty(found)) selected = found;
|
||||
|
||||
LocalizationProvider.LanguageChanged += (s, c) =>
|
||||
{
|
||||
var found2 = mapping.FirstOrDefault(kv => string.Equals(kv.Value, c, StringComparison.OrdinalIgnoreCase)).Key;
|
||||
if (!string.IsNullOrEmpty(found2)) selected = found2;
|
||||
StateHasChanged();
|
||||
};
|
||||
}
|
||||
|
||||
private async Task OnChange(ChangeEventArgs e)
|
||||
{
|
||||
if (e?.Value is string val)
|
||||
{
|
||||
selected = val;
|
||||
await LocalizationProvider.SetCultureAsync(selected);
|
||||
|
||||
try
|
||||
{
|
||||
// Use NavigationManager to inspect and modify the current client-side path
|
||||
var relative = Navigation.ToBaseRelativePath(Navigation.Uri).Trim('/');
|
||||
var segments = string.IsNullOrEmpty(relative) ? Array.Empty<string>() : relative.Split('/', StringSplitOptions.RemoveEmptyEntries);
|
||||
var mapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{ "zh", "zh-Hans" },
|
||||
{ "en", "en-US" }
|
||||
};
|
||||
|
||||
string newUrl;
|
||||
if (segments.Length > 0 && mapping.ContainsKey(segments[0]))
|
||||
{
|
||||
// replace existing locale prefix
|
||||
var remaining = segments.Length > 1 ? "/" + string.Join('/', segments.Skip(1)) : "/";
|
||||
newUrl = "/" + selected + remaining;
|
||||
}
|
||||
else
|
||||
{
|
||||
// keep current path, but trigger remount by navigating to same URI
|
||||
newUrl = Navigation.Uri;
|
||||
}
|
||||
|
||||
// trigger client-side navigation (no hard reload) so components remount and re-evaluate localizer
|
||||
Navigation.NavigateTo(newUrl, forceLoad: false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// fallback: just request UI refresh
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user