原文鏈接:https://blazor-university.com/routing/navigating-our-app-via-code/
通過代碼導航
源代碼[1]
從 Blazor 訪問瀏覽器導航是通過 NavigationManager
服務提供的。這可以使用 razor 文件中的 @inject
或 CS 文件中的 [Inject]
屬性注入到 Blazor 組件中。
NavigationManager
服務有兩個特別的成員;NavigateTo
和 LocationChanged
。
LocationChanged
事件將在檢測導航事件[2]中更詳細地解釋。
NavigateTo 方法
NavigationManager.NavigateTo
方法使 C# 代碼能夠控制瀏覽器的 URL。與截獲的導航一樣,瀏覽器實際上并不導航到新的 URL。相反,瀏覽器中的 URL 被替換,之前的 URL 被插入到瀏覽器的導航歷史中,但沒有向服務器請求新頁面的內容。通過 NavigateTo
進行的導航將觸發 LocationChanged
事件,傳遞新 URL 并為 IsNavigationIntercepted
傳遞 false
。
對于此示例,我們將再次更改標準 Blazor 模板。我們將使用我們之前在路由參數[3]和可選路由參數[4]中學到的知識。
首先,刪除 Index.razor 和 FetchData.razor 頁面,并刪除 NavMenu.razor 文件中指向這些頁面的鏈接。同樣在 NavMenu
中,將 counter
鏈接的 href
更改為 為 href=""
,因為我們將使其成為默認頁面。
編輯 Counter.razor
并給它兩個路由,“/” 和 “/counter/{CurrentCount:int}”,同時確保它來自 CounterBase
類,這樣我們就可以在瀏覽器的控制臺窗口中看到導航日志 - CounterBase.cs
文件之前在 OnLocationChanged
部分中進行了概述。
@page?"/"
@page?"/counter/{CurrentCount:int}"
@inherits?CounterBase
我們還需要更改 currentCount
字段,使其成為具有 getter
和 setter
的屬性,并將其裝飾為 [Parameter]
。請注意,它也已從 camelCase
重命名為 PascalCase
。
[Parameter]
public?int?CurrentCount?{?get;?set;?}
我們現在有一個 counter 頁面,可以簡單地訪問應用程序的主頁,也可以通過指定 /counter/X
來訪問,其中 X
是一個整數值。
NavigationManager
被注入到我們的 CounterBase
類中,因此可以在 Counter.razor
文件中訪問。
@code?{[Parameter]public?int?CurrentCount?{?get;?set;?}bool?forceLoad;void?AlterBy(int?adjustment){int?newCount?=?CurrentCount?+?adjustment;UriHelper.NavigateTo("/counter/"?+?newCount,?forceLoad);}
}
我們將從兩個按鈕調用 AlterBy
方法,一個用于增加 CurrentCount
,一個用于減少它。還有一個用戶可以選擇的選項 forceLoad
,它將在調用 NavigateTo
時設置相關參數,以便我們看到差異。整個文件最終應如下所示:
@page?"/"
@page?"/counter/{CurrentCount:int}"
@implements?IDisposable
@inject?NavigationManager?NavigationManager<h1>Counter?value?=?@CurrentCount</h1><div?class="form-check"><input?@bind=@forceLoad?type="checkbox"?class="form-check-input"?id="ForceLoadCheckbox"?/><label?class="form-check-label"?for="ForceLoadCheckbox">Force?page?reload?on?navigate</label>
</div><div?class="btn-group"?role="group"><button?@onclick=@(?()?=>?AlterBy(-1)?)?class="btn?btn-primary">-</button><input?value=@CurrentCount?readonly?class="form-control"?/><button?@onclick=@(?()?=>?AlterBy(1)?)?class="btn?btn-primary">+</button>
</div>
<a?class="btn?btn-secondary"?href="/Counter/0">Reset</a>
<p><em>Page?redirects?to?ibm.com?when?count?hits?10!</em>
</p>@code?{[Parameter]public?int?CurrentCount?{?get;?set;?}bool?forceLoad;void?AlterBy(int?adjustment){int?newCount?=?CurrentCount?+?adjustment;if?(newCount?>=?10)NavigationManager.NavigateTo("https://ibm.com");NavigationManager.NavigateTo("/counter/"?+?newCount,?forceLoad);}protected?override?void?OnInitialized(){//?Subscribe?to?the?eventNavigationManager.LocationChanged?+=?LocationChanged;base.OnInitialized();}private?void?LocationChanged(object?sender,?LocationChangedEventArgs?e){string?navigationMethod?=?e.IsNavigationIntercepted???"HTML"?:?"code";System.Diagnostics.Debug.WriteLine($"Notified?of?navigation?via?{navigationMethod}?to?{e.Location}");}void?IDisposable.Dispose(){//?Unsubscribe?from?the?event?when?our?component?is?disposedNavigationManager.LocationChanged?-=?LocationChanged;}
}
單擊 -
或 +
按鈕將調用 AlterBy
方法,該方法將指示 NavigationManager
服務導航到 /counter/X
,其中 X
是調整后的 CurrentCount
的值——在瀏覽器的控制臺中產生以下輸出:
WASM:通過代碼通知導航到 http://localhost:6812/counter/1
WASM:通過代碼通知導航到 http://localhost:6812/counter/2
WASM:通過代碼通知導航到 http://localhost:6812/counter/3
WASM:通過代碼通知導航到 http://localhost:6812/counter/4
單擊重置鏈接將導航到 /counter/0
,重置 CurrentCount
的值。
WASM:通過代碼通知導航到 http://localhost:6812/counter/1
WASM:通過代碼通知導航到 http://localhost:6812/counter/2
WASM:通過代碼通知導航到 http://localhost:6812/counter/3
WASM:通過代碼通知導航到 http://localhost:6812/counter/4
WASM:通過 HTML 通知導航到 http://localhost:6812/Counter/0
ForceLoad
forceLoad
參數指示 Blazor 繞過其自己的路由系統,而是讓瀏覽器實際導航到新 URL。這將導致對服務器的 HTTP 請求以檢索要顯示的內容。
請注意,導航到站外 URL 不需要強制加載。調用 NavigateTo
到另一個域將調用完整的瀏覽器導航。
使用本節的 GitHub 示例。在瀏覽器的控制臺窗口中查看 IsNavigationIntercepted
在通過按鈕和重置鏈接導航時有何不同,并在瀏覽器的網絡窗口中查看根據您是否:
將 forceLoad 設置為 false 進行導航。
將 forceLoad 設置為 true 進行導航。
導航到站外 URL。
要觀察最后一種情況,您可能希望更新 AdjustBy
方法以在 CurrentValue
傳遞特定值時進行站外導航。
void?AlterBy(int?adjustment)
{int?newCount?=?CurrentCount?+?adjustment;if?(newCount?>=?10)NavigationManager.NavigateTo("https://ibm.com");NavigationManager.NavigateTo("/counter/"?+?newCount,?forceLoad);
}
參考資料
[1]
源代碼: https://github.com/mrpmorris/blazor-university/tree/master/src/Routing/NavigatingViaCode