Ven*_*sky 7 blazor blazor-server-side blazor-client-side
在使用 blazor 时,我希望能够“返回”到我之前所在的页面。
我发现了这个问题,看起来它是一个死胡同?
这个功能太基础了,我不敢相信它不存在。
是否有任何走动可以使此“返回”功能?
请注意,我不能使用window.goBack或history.goBack因为我的应用程序没有创建任何历史记录,也不应该创建任何历史记录。
“创建”历史记录的唯一方法是使用forceLoad选项,Navigation.NavigateTo但如果我这样做,它会尝试再次加载我的整个应用程序,这很慢,我不想。
小智 32
使用 JavaScript 怎么样?
@inject IJSRuntime JSRuntime
// Go back in browser using Javascript on a Razor Page
private async Task GoBack()
{
await JSRuntime.InvokeVoidAsync("history.back");
}
Run Code Online (Sandbox Code Playgroud)
或者,如果不需要绘制按钮并处理事件,则使用标准链接:
<a onclick="history.back();">Return</a>
Run Code Online (Sandbox Code Playgroud)
Pav*_*kov 17
我最终得到了一个稍微改进的解决方案,它包装/封装了 NavigationManager,将所有内容保留在一个位置,并且不依赖于页面或其他东西。它还将历史缓冲区大小保持在某个合理的范围内。
导航.cs
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Routing;
namespace MyApp
{
public class Navigation : IDisposable
{
private const int MinHistorySize = 256;
private const int AdditionalHistorySize = 64;
private readonly NavigationManager _navigationManager;
private readonly List<string> _history;
public Navigation(NavigationManager navigationManager)
{
_navigationManager = navigationManager;
_history = new List<string>(MinHistorySize + AdditionalHistorySize);
_history.Add(_navigationManager.Uri);
_navigationManager.LocationChanged += OnLocationChanged;
}
/// <summary>
/// Navigates to the specified url.
/// </summary>
/// <param name="url">The destination url (relative or absolute).</param>
public void NavigateTo(string url)
{
_navigationManager.NavigateTo(url);
}
/// <summary>
/// Returns true if it is possible to navigate to the previous url.
/// </summary>
public bool CanNavigateBack => _history.Count >= 2;
/// <summary>
/// Navigates to the previous url if possible or does nothing if it is not.
/// </summary>
public void NavigateBack()
{
if (!CanNavigateBack) return;
var backPageUrl = _history[^2];
_history.RemoveRange(_history.Count - 2, 2);
_navigationManager.NavigateTo(backPageUrl);
}
// .. All other navigation methods.
private void OnLocationChanged(object sender, LocationChangedEventArgs e)
{
EnsureSize();
_history.Add(e.Location);
}
private void EnsureSize()
{
if (_history.Count < MinHistorySize + AdditionalHistorySize) return;
_history.RemoveRange(0, _history.Count - MinHistorySize);
}
public void Dispose()
{
_navigationManager.LocationChanged -= OnLocationChanged;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以将此类作为单例服务添加到依赖注入并初始化。
程序.cs
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
namespace MyApp
{
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
builder.Services.AddSingleton<Navigation>();
// .. other services.
var host = builder.Build();
await Initialize(host);
await host.RunAsync();
}
private static async Task Initialize(WebAssemblyHost host)
{
host.Services.GetService<Navigation>();
// .. other initialization calls.
}
}
}
Run Code Online (Sandbox Code Playgroud)
之后,您可以使用 Inject 指令/属性在任何您想要的地方使用它。
SomePage.cshtml
@page "/SomePage"
@inject Navigation Navigation
<h3>SomePage</h3>
<button @onclick="NavigateBackClick">Navigate Back</button>
@code {
private void NavigateBackClick()
{
Navigation.NavigateBack();
}
}
Run Code Online (Sandbox Code Playgroud)
SomeService.cs
namespace MyApp
{
public class SomeService
{
private readonly Navigation _navigation;
public SomeService(Navigation navigation)
{
_navigation = navigation;
}
public void SomeMethod()
{
// ...
_navigation.NavigateBack();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Tay*_*ite 12
我将上面迪奥戈的答案修改为我认为更优雅的解决方案。
首先创建一个BasePageComponent.cs类,继承自该类ComponentBase:
// Using statements/namespace go here
[Authorize]
public class BasePageComponent: ComponentBase
{
[Inject]
protected NavigationManager _navManager { get; set; }
[Inject]
protected PageHistoryState _pageState { get; set; }
public BasePageComponent(NavigationManager navManager, PageHistoryState pageState)
{
_navManager = navManager;
_pageState = pageState;
}
public BasePageComponent()
{
}
protected override void OnInitialized()
{
base.OnInitialized();
_pageState.AddPage(_navManager.Uri);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是您的每个页面都将继承的内容。它处理注入PageHistoryState服务以及附加新导航的页面。它在实际页面的“幕后”完成这一切。
现在,在给定页面中,您继承自BasePageComponent:
@page "/workouts/new"
@inherits BasePageComponent
/* ...RenderFragments/Razor view here...*/
@code {
/* ...properties here...*/
// This is an example of how to consume the _navManager and _pageState objects if desired, without any boilerplate code.
private void OnCancel()
{
_navManager.NavigateTo(_pageState.PreviousPage());
}
}
Run Code Online (Sandbox Code Playgroud)
在我的示例组件中(为了简洁而删除),它向页面历史堆栈添加了一个新元素,除了继承自BasePageComponent. 泰勒
Dio*_*ves 11
你需要的是一个页面历史状态管理器:
对于以下示例,我使用的是 Blazor Wasm,但您也可以在 Blazor Server 中使用此示例。
在客户端应用程序中,我添加了这个类:PageHistoryState:
公共类 PageHistoryState
{
private List<string> previousPages;
公共 PageHistoryState()
{
previousPages = new List<string>();
}
public void AddPageToHistory(string pageName)
{
previousPages.Add(pageName);
}
公共字符串 GetGoBackPage()
{
if (previousPages.Count > 1)
{
// 你在初始化时添加了一个页面,所以你需要从最后一个返回第二个
返回 previousPages.ElementAt(previousPages.Count - 2);
}
// 无法返回,因为你导航不够
返回 previousPages.FirstOrDefault();
}
public bool CanGoBack()
{
返回 previousPages.Count > 1;
}
}
然后将此类作为单例添加到服务中:
builder.Services.AddSingleton<PageHistoryState>();
将其注入您的页面:
@inject WasmBlazor.Client.PageHistoryState PageHistoryState
Run Code Online (Sandbox Code Playgroud)
在我的标记中,我检查了是否可以返回页面:
@if (PageHistoryState.CanGoBack())
{
<a href="@PageHistoryState.GetGoBackPage()">返回</a>
}
我已经覆盖了 OnInitialized()
protected override void OnInitialized()
{
PageHistoryState.AddPageToHistory("/counter");
base.OnInitialized();
}
我在“获取数据”页面中做了同样的事情,我可以在不需要 JSInterop 的情况下返回。
| 归档时间: |
|
| 查看次数: |
5844 次 |
| 最近记录: |