Blazor:如何动态更改URL?

时间:2020-02-18 10:42:09

标签: blazor

我有一个页面,该页面将字符串bookingReference作为其路由参数Booking/{bookingReference}

此页面是父组件,内部是子组件,用于管理预订详细信息。预订详细信息更新后,子级组件会回调父级。

@page "/Operations/Bookings/{bookingReference}"


<div class="header">
   <h1> @Booking.BookingReference </h1>
</div>

<div>
   <BookingDetails Booking="Booking" OnUpdateBooking="UpdateBooking" />
</div>


@code {

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

    private Booking Booking { get; set; }

    void UpdateBooking(Booking booking)
    {
        Booking = booking;
        StateHasChanged();
    }
}

BookingDetails组件如下所示:

<EditForm Model="FormState" OnValidSubmit="@saveChanges">
   //inputs etc.
</EditForm>

@code {
    [Parameter]
    public Booking Booking { get; set; }

    [Parameter]
    public EventCallback<Booking> OnUpdateBooking { get; set; }

private async Task saveChanges()
{
        // update booking object
        Booking.BookingReference = FormState.BookingReference;

        try
        {
            Booking = await BookingService.UpdateBooking(Booking);
            await OnUpdateBooking.InvokeAsync(Booking);
            Toaster.Success("Booking updated successfully");
        }
        catch
        {
            Toaster.Error("Failed to update booking");
        }
    }
}

用户可以从子组件中更新预订参考,从而更改页面的标题-很好,一切正常。

但是,我也想将URL更改为更新的bookingReference-在不强制刷新的情况下,有什么方法可以实现这一目标?

2 个答案:

答案 0 :(得分:3)

好吧,现在更改URL中的BookingReference值的唯一方法是使用新的BookingReference导航到当前URL。 请注意,此操作不会重新加载或刷新页面组件。这是一种重新渲染操作。 OnInitialized生命周期仅执行一次,这表明这些组件没有被销毁然后重新创建。它们只是重新渲染。这是要走的路。

@code {

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

private Booking Booking { get; set; }

void UpdateBooking(Booking booking)
{
    Booking = booking;
    NavigationManager.NavigateTo($"/{Booking.BookingReference}");

}
}

答案 1 :(得分:2)

如果通过“强制刷新”表示重新加载页面,则答案为肯定。您不必重新加载页面,但是必须重新渲染页面才能刷新视图(不是重新加载而是重新渲染)。重新加载页面时,将重新创建页面组件和嵌入式组件。重新渲染页面时,页面组件和嵌入式组件不会被破坏,并且仅应用Html diff来反映这一点。

您没有发布BookingDetails组件的代码,因此我的答案仅基于猜测

<BookingDetails Booking="Booking" OnUpdateBooking="UpdateBooking" />


Your BookingDetails component should define a property named OnUpdateBooking
of type *EventCallback<Booking>* like this:



[Parameter]
public EventCallback<Booking> OnUpdateBooking {get; set;}

它还应该定义一个名为Booking的参数属性,这是从父组件传递来的对象。

// Supporting variable
private Booking booking;

[Parameter]
public Booking Booking 
{ 
  get => booking; 
set 
{
   if( booking != value)
   {
      booking = value;
      OnUpdateBooking.InvokeAsync(value);
   } 
}

注意:Booking属性存储从父组件传递的值。当其值通过子组件中的代码更改时,您应该调用OnUpdateBooking'delegate',并将新更新的值传递给它。此值将传递回父组件中定义的UpdateBooking方法,将传递的值分配给专用的Booking字段,然后重新呈现父页面。现在您应该看到url更改以反映这一点。

注意:从UpdateBooking中删除对StateHasChanged方法的调用。没有必要。