web-dev-qa-db-ja.com

Blazorコンポーネントの現在のURLを取得する

要素に特定のスタイルを適用する必要があるかどうかを確認するには、現在のページのURLを知る必要があります。以下のコードは例です。

@using Microsoft.AspNetCore.Blazor.Services
@inject IUriHelper UriHelper
@implements IDisposable

<h1>@url</h1>
<nav>
    <div class="nav-wrapper">
        <a href="#" class="brand-logo">Blazor</a>
        <ul id="nav-mobile" class="right hide-on-med-and-down">
            <li>
                <NavLink href="/" Match=NavLinkMatch.All>
                    Home
                </NavLink>
            </li>
            <li>
                <NavLink href="/counter">
                    Counter
                </NavLink>
            </li>
            <li>
                <NavLink href="/fetchdata">
                    Fetch data
                </NavLink>
            </li>
        </ul>
    </div>
</nav>

@functions {

    private string url = string.Empty;

    protected override void OnInit()
    {
        url = UriHelper.GetAbsoluteUri();
        UriHelper.OnLocationChanged += OnLocationChanged;
    }

    private void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        url = newUriAbsolute;
    }

    public void Dispose()
    {
        UriHelper.OnLocationChanged -= OnLocationChanged;
    }
}

BlazorリポジトリのNavLinkコンポーネントで使用されているのと同じアプローチを使用しましたが、機能しませんでした。何か案は?。

17
Carlos L.

UriNavigationManagerプロパティを使用)クラス。

使い方

.razorページで使用する前に、インジェクションから入手してください:

@inject NavigationManager MyNavigationManager

または、「分離コード」体験を好む場合は.csでこのようにします。

using Microsoft.AspNetCore.Components;
...
[Inject] 
public NavigationManager MyNavigationManager {get; set;}

サンプル

@page "/navigate"
@inject NavigationManager MyNavigationManager

<h1>Current url</h1>

<p>@(MyNavigationManager.Uri)</p>

ナビゲーションの詳細(NavigateTo、BaseUri、ToAbsoluteUri、ToBaseRelativePath、...): RIおよびナビゲーション状態ヘルパー

NavigationManagerチートシート

MyNavigationManager.Uri
#> https://localhost:5001/counter/3?q=hi

MyNavigationManager.BaseUri`
#> https://localhost:5001/

MyNavigationManager.NavigateTo("http://new location")
#> Navigates to new location

MyNavigationManager.LocationChanged
#> An event that fires when the navigation location has changed.

MyNavigationManager.ToAbsoluteUri("pepe")
#> https://localhost:5001/pepe

MyNavigationManager.ToBaseRelativePath( MyNavigationManager.BaseUri)
#> counter/3?q=hi

Helper: AddQueryParm( "q2", "bye" )
#> https://localhost:5001/counter/3?q=hi&q2=bye

Helper: GetQueryParm( "q" )
#> hi

ヘルパーコード:

@code {

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

// blazor: add parm to url
string AddQueryParm(string parmName, string parmValue)
{
    var uriBuilder = new UriBuilder(MyNavigationManager.Uri);
    var q = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
    q[parmName] = parmValue;
    uriBuilder.Query = q.ToString();
    var newUrl = uriBuilder.ToString();
    return newUrl;
}

// blazor: get query parm from url
string GetQueryParm(string parmName)
{
    var uriBuilder = new UriBuilder(MyNavigationManager.Uri);
    var q = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
    return q[parmName] ?? "";
}

}
29
dani herrera

ページまたはコンポーネントのOnLocationChangedイベントへの接続は、ロードされてdemanndで破棄されるため、役に立ちません。

破棄されないので、app.cshtmlでこのイベントに登録する必要があります。

2
Flores

IUriHelperのLocationChangeをリッスンする必要があります。これにより、関数がトリガーされて、たとえば次のようになります。

@using Microsoft.AspNetCore.Blazor.Components
@using Microsoft.Extensions.Logging
@inject Microsoft.AspNetCore.Blazor.Services.IUriHelper UriHelper
@inject ILogger<NavItem> logger

<li class="m-menu__item @(Active ? "m-menu__item--active" : "")">
    <a href=@Url class="m-menu__link ">
        <span class="m-menu__item-here"></span>
        <i class="m-menu__link-icon @Icon"></i>
        <span class="m-menu__link-text">@Text</span>
    </a>
</li>

@functions {
    protected override void OnInit()
    {
        UriHelper.OnLocationChanged += OnLocationChanges;
    }
    [Parameter]
    private string Url { get; set; }
    [Parameter]
    private string Icon { get; set; }
    [Parameter]
    private string Text { get; set; }
    private bool Active = false;
    private void OnLocationChanges(object sender, string newLocation)
    {
        bool active = newLocation.Contains(Url);
        if(active != Active) //Only re-render the components that need it
        {
            Active = active;
            StateHasChanged();
            logger.LogInformation("Location Change To:" + newLocation);
        }
    }
}
0
Ben Vertonghen