یک نکتهی تکمیلی: تنظیم پویای عنوان صفحات در برنامههای Blazor
برای تنظیم پویای عنوان یک صفحهی وب، نیاز است با DOM API مرورگر به صورت مستقیم کار کرد. برای مثال فایل wwwroot\main.js را که مدخل آن به کامپوننت Host_ و یا صفحهی index.html اضافه میشود، به صورت زیر تکمیل میکنیم:
اکنون میخواهیم این متد جاوااسکریپتی را که مستقیما با شیء document کار میکند، در کامپوننت جدید Client\Shared\PageTitle.razor استفاده کنیم:
در اینجا کامپوننت جدیدی تعریف شدهاست که به محض تنظیم مقدار پارامتر عنوان آن، سبب فراخوانی متد جاوا اسکریپتی blazorSetTitle میشود. برای نمونه روش استفادهی از آن در کامپوننت Counter، جهت نمایش عنوانی پویا، به محض تغییر مقدار شمارشگر، به صورت زیر میتواند باشد:
این روش در برنامههای Blazor Server کار نخواهد کرد و در حین فراخوانی متد InvokeVoidAsync یک NullReferenceException مشاهده میشود؛ چون این نوع برنامههای Blazor Server به همراه یک مرحلهی pre-render در سمت سرور هستند که ابتدا، کار تهیهی HTML ای را که باید به سمت مرورگر ارسال کنند، به پایان میرسانند. در این مرحله خبری از DOM نیست که بتوان به آن دسترسی یافت و تغییری را در آن ایجاد کرد.
برای رفع این مشکل همانطور که در مطلب جاری نیز عنوان شد، باید از روال رویدادگردان OnAfterRenderAsync استفاده کرد. در این حالت کدهای کامپوننت PageTitle.razor به صورت زیر تغییر میکنند:
روال رویدادگردان OnAfterRenderAsync پس از اینکه کار بارگذاری و تشکیل کامل DOM در مرورگر انجام شد، فراخوانی میشود. به همین جهت دیگر دسترسی به شیء document.title، سبب بروز یک NullReferenceException نخواهد شد.
یک نکته: قرار است در Blazor 6x، کامپوننتهای جدید Title، Link و Meta جهت تنظیم اطلاعات تگ head صفحه، به صورت استاندارد اضافه شوند:
برای تنظیم پویای عنوان یک صفحهی وب، نیاز است با DOM API مرورگر به صورت مستقیم کار کرد. برای مثال فایل wwwroot\main.js را که مدخل آن به کامپوننت Host_ و یا صفحهی index.html اضافه میشود، به صورت زیر تکمیل میکنیم:
window.JsFunctionHelper = { blazorSetTitle: function (title) { document.title = title; } };
@inject IJSRuntime JSRuntime @code { [Parameter] public string Title { get; set; } protected override async Task OnParametersSetAsync() { await JSRuntime.InvokeVoidAsync("JsFunctionHelper.blazorSetTitle", Title); } }
@page "/counter" <PageTitle Title="@GetPageTitle()" /> <h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } private string GetPageTitle() => $"Counter ({currentCount})"; }
برای رفع این مشکل همانطور که در مطلب جاری نیز عنوان شد، باید از روال رویدادگردان OnAfterRenderAsync استفاده کرد. در این حالت کدهای کامپوننت PageTitle.razor به صورت زیر تغییر میکنند:
@inject IJSRuntime JSRuntime @code { [Parameter] public string Title { get; set; } protected override async Task OnAfterRenderAsync(bool firstRender) { await JSRuntime.InvokeVoidAsync("JsFunctionHelper.blazorSetTitle", Title); } }
یک نکته: قرار است در Blazor 6x، کامپوننتهای جدید Title، Link و Meta جهت تنظیم اطلاعات تگ head صفحه، به صورت استاندارد اضافه شوند:
<Title Value="@title" /> <Meta name="description" content="Modifying the head from a Blazor component." /> <Link href="main.css" rel="stylesheet" />