【问题标题】:NavLink updating URL but does not reloading page in BlazorNavLink 更新 URL 但不在 Blazor 中重新加载页面
【发布时间】:2020-04-21 09:33:56
【问题描述】:

我有一个 ProjectBase.razor 页面,用于创建、查看和编辑项目。以下路线都将带您到此页面:

/project/view/{projNum}
/project/create/
/project/edit/{projNum}

我的导航菜单中还有一个 Navlink,可让您创建新项目:

<NavLink class="nav-link" href="/Project/Create" Match="NavLinkMatch.All" >
    <span aria-hidden="true">New Project</span>
</NavLink>

如果我在同一页面的查看/编辑功能上单击该链接,则 URL 将更改为“/Project/Create”,但页面本身不会刷新或重新加载。有没有办法通过 NavLink 强制执行此操作?还是我需要添加一个 OnClick 函数来执行此操作?

【问题讨论】:

  • 您没有提供足够的信息,因此很难找到问题所在。但是,不会进行路由。首先,NavLink 组件的 href 属性应该是 href="project/create",没有首字母“/”。您是否为参数定义了公共参数属性?如果您的组件名为 ProjectBase,它应该在路由模板中显示为 projectbase 而不是项目...
  • 确认我的理解:如果您在浏览器中输入这些 URL,页面加载是否正确?只是当您尝试通过单击 NavLink 转到这些链接时,页面才不会加载? (但是 URL 改变了?)
  • 凯尔,没错!只有当它在同一页面内导航时。如果我在一个完全不同的 Razor 页面上,它会很好地导航和加载。

标签: asp.net-core blazor


【解决方案1】:

在页面的代码块中创建并使用 OnParametersSetAsync 任务。当参数改变时会触发这个事件。

@code
protected override async Task OnParametersSetAsync()
{
// This event will fire when the parameters change
// Put your code here.  

}

【讨论】:

  • 仅仅包含 OnParametersSetAsync() 方法并不能真正解决问题。当你写“把你的代码放在这里”时,你对解决 OPs 问题的代码有什么建议?
  • OP 对参数也不是很具体。使用 Blazor,如果您要导航到页面并传递参数,如果您只是导航回在代码块中使用 OnInitSetAsync 作为页面初始化的同一基本 URL,则页面不会刷新 - 即使参数不同。这个代码块在初始加载时只触发一次——因此为什么一旦已经加载一次就导航回那里并不会刷新 pgae。另一方面,如果使用 OnParametersSetAsync(),则每次将参数传递给页面时都会触发,从而强制重新加载页面。
  • 不,这是不正确的。每当将参数传递到页面时,OnParametersSetAsync() 都不会强制重新加载。当传入的参数与之前传入的参数相比 不同 时,它将强制重新加载。因此,如果您的参数是 int,并且您使用 NavLink 访问您的页面,则该 int 将默认为为 0,因为这就是 int 所做的。如果您随后再次单击相同的 NavLink,则该 int 仍将为 0,并且您不会重新加载页面。换句话说:您必须通知框架该参数现在不是 0。问题是如何。答案将解决 OP 的问题。
  • 很好的答案!实际上,您应该在父组件中调用此事件,而不是在子组件中。
  • Linus 是正确的,如果参数相同,它将不起作用。保存数据后,我通过设置 id 参数克服了这个问题。即 NavLink 是“myapp”,默认为 id=0。页面保存对象后,我设置参数 id=newIdFromDatabase 和 OnParametersSetAsync 触发器。
【解决方案2】:

是的,使用 Microsoft.AspNetCore.Components.NavigationManager 之类的东西及其 NavigateTo 函数并将 forceLoad 设置为 true 将完成您正在寻找的内容。

当然是的,这将需要您设置一个 onclick 功能,但这是我最终为站点范围的搜索页面完成类似操作的方式,从技术上讲,它的 URL 从未在查询字符串搜索值之外更改我通过了。

话虽如此,仅使用 NavLinks 可能是一种不错的方法。当我不使用移动设备时,我会更新我的答案。

【讨论】:

  • 使用 forceLoad 适用于我的大多数场景,但我很好奇您对 NavLinks 采取的方法。希望你有带宽回来回答! :)
  • 以防万一有人想知道这个答案的代码是什么样的:NavigationManager.NavigateTo($"/your/route", true);
【解决方案3】:

我有同样的问题。我的解决方案是......

创建新页面

@page "/project/create/"
<ProjectBase></ProjectBase>

就是这样!从 ProjectBase 页面中删除 @page 指令 for(/project/create/)

一切都会按预期工作...现在为您拥有的所有页面执行此操作。

【讨论】:

  • 由于Blazor的设计,我认为这是理想的解决方案。
  • 对于我们 Blazor 菜鸟,我假设我们创建一个具有任何名称的页面,例如ProjectBaseXyz.razor,内容如上。
【解决方案4】:

在您的情况下,您必须按照 Rod Weir 所述进行以下更改,我只是在扩展答案。

 /project/view/{projNum}
 /project/create/
 /project/edit/{projNum}

对于上述查询参数,您必须在代码中定义 [Parameter]。

[Parameter]
public string projNum {get;set;}

然后添加方法

protected override async Task OnParametersSetAsync()
{

  var projectDetail = await getProjectDetails(projNum); // ProgNum will change as it get changes in url, you don't have to do anything extra here.
}

强制页面重新加载会让您遇到一些其他问题,它会得到正确的结果,但页面行为会改变。页面上还有其他组件,例如 header/left Nav/ 等,如果它们是动态的,则不会更改。它将迫使您进行更改并在所有组件中强制重新加载。用户体验也会受到影响。

希望对您有所帮助。

【讨论】:

    【解决方案5】:

    这是设计使然。页面本身不会刷新或重新加载,因为&lt;NavLink&gt; 不会向服务器发送请求(F12 进行检查)并且它重定向到客户端上的同一页面,因此没有任何更新。

    如果您在浏览器中输入这些 URL,它们将发送请求,然后刷新页面。

    一种解决方法是您可以根据当前路线显示不同的内容。

    @page "/project/view/{projNum}"
    @page "/project/create/"
    @page "/project/edit/{projNum}"
    @using Models
    <h3>ProjectBase</h3>
    
    @if (projNum == null)
    {
    <EditForm Model="@createModel" OnValidSubmit="@HandleValidSubmit">
        <DataAnnotationsValidator />
        <ValidationSummary />
    
        <InputText id="name" @bind-Value="createModel.Name" />
    
        <button type="submit">Create</button>
    </EditForm>
    }
    else
    {
    
    
    <EditForm Model="@exampleModel" OnValidSubmit="@HandleValidSubmit">
        <DataAnnotationsValidator />
        <ValidationSummary />
    
        <InputText id="name" @bind-Value="exampleModel.Name" />
    
        <button type="submit">Submit</button>
    </EditForm>
    }
    @code {
    
    
        [Parameter]
        public string projNum { get; set; }
    
        private ExampleModel createModel = new ExampleModel();
        private ExampleModel exampleModel = new ExampleModel();
    
        protected override void OnInitialized()
        {
            exampleModel.Name = projNum;
        }
    
    
    
        private void HandleValidSubmit()
        {
            //your logic
            Console.WriteLine("OnValidSubmit");
        }
    }
    

    【讨论】:

      【解决方案6】:

      在我的组件中,我已经覆盖了OnInitializedAsync,以便通过 API 调用来获取我的数据。

      我的解决方案如下所示:

              protected override async Task OnInitializedAsync()
              {
                 // Make your API call or whatever else you use to initialize your component here
              }
      
              protected override async Task OnParametersSetAsync()
              {
                  await OnInitializedAsync();
              }
      

      【讨论】:

        猜你喜欢
        • 2021-08-10
        • 2014-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多