ASP.NET Core Blazor JavaScript dengan penyajian sisi server statis (SSR statis)
Artikel ini menjelaskan cara memuat JavaScript (JS) dalam dengan penyajian sisi server statis (SSR statis) dan navigasi yang ditingkatkanBlazor Web App.
Beberapa aplikasi bergantung pada JS untuk melakukan tugas inisialisasi yang khusus untuk setiap halaman. Saat menggunakan Blazorfitur navigasi yang ditingkatkan, yang memungkinkan pengguna untuk menghindari memuat ulang seluruh halaman, spesifik halaman JS mungkin tidak dijalankan lagi seperti yang diharapkan setiap kali navigasi halaman yang ditingkatkan terjadi.
Untuk menghindari masalah ini, kami tidak merekomendasikan untuk mengandalkan elemen khusus <script>
halaman yang ditempatkan di luar file tata letak yang diterapkan ke komponen. Sebagai gantinya, skrip harus mendaftarkan penginisialisasi JSafterWebStarted
untuk melakukan logika inisialisasi dan menggunakan pendengar peristiwa (blazor.addEventListener("enhancedload", callback)
) untuk mendengarkan pembaruan halaman yang disebabkan oleh navigasi yang ditingkatkan.
Contoh berikut menunjukkan salah satu cara untuk mengonfigurasi JS kode untuk dijalankan saat halaman yang dirender secara statis dengan navigasi yang ditingkatkan awalnya dimuat atau diperbarui.
Contoh komponen berikut PageWithScript
adalah komponen dalam aplikasi yang mengharuskan skrip dijalankan dengan SSR statis dan navigasi yang disempurnakan. Contoh komponen berikut menyertakan PageScript
komponen dari Razor pustaka kelas (RCL) yang ditambahkan ke solusi nanti dalam artikel ini.
Components/Pages/PageWithScript.razor
:
@page "/page-with-script"
@using BlazorPageScript
<PageTitle>Enhanced Load Script Example</PageTitle>
<PageScript Src="./Components/Pages/PageWithScript.razor.js" />
Welcome to my page.
Blazor Web AppDi , tambahkan file yang dikolokasi JS berikut:
onLoad
dipanggil ketika skrip ditambahkan ke halaman.onUpdate
dipanggil ketika skrip masih ada di halaman setelah pembaruan yang ditingkatkan.onDispose
dipanggil ketika skrip dihapus dari halaman setelah pembaruan yang ditingkatkan.
Components/Pages/PageWithScript.razor.js
:
export function onLoad() {
console.log('Loaded');
}
export function onUpdate() {
console.log('Updated');
}
export function onDispose() {
console.log('Disposed');
}
Razor Di Pustaka Kelas (RCL) (contoh RCL diberi nama BlazorPageScript
), tambahkan modul berikut.
wwwroot/BlazorPageScript.lib.module.js
:
const pageScriptInfoBySrc = new Map();
function registerPageScriptElement(src) {
if (!src) {
throw new Error('Must provide a non-empty value for the "src" attribute.');
}
let pageScriptInfo = pageScriptInfoBySrc.get(src);
if (pageScriptInfo) {
pageScriptInfo.referenceCount++;
} else {
pageScriptInfo = { referenceCount: 1, module: null };
pageScriptInfoBySrc.set(src, pageScriptInfo);
initializePageScriptModule(src, pageScriptInfo);
}
}
function unregisterPageScriptElement(src) {
if (!src) {
return;
}
const pageScriptInfo = pageScriptInfoBySrc.get(src);
if (!pageScriptInfo) {
return;
}
pageScriptInfo.referenceCount--;
}
async function initializePageScriptModule(src, pageScriptInfo) {
if (src.startsWith("./")) {
src = new URL(src.substr(2), document.baseURI).toString();
}
const module = await import(src);
if (pageScriptInfo.referenceCount <= 0) {
return;
}
pageScriptInfo.module = module;
module.onLoad?.();
module.onUpdate?.();
}
function onEnhancedLoad() {
for (const [src, { module, referenceCount }] of pageScriptInfoBySrc) {
if (referenceCount <= 0) {
module?.onDispose?.();
pageScriptInfoBySrc.delete(src);
}
}
for (const { module } of pageScriptInfoBySrc.values()) {
module?.onUpdate?.();
}
}
export function afterWebStarted(blazor) {
customElements.define('page-script', class extends HTMLElement {
static observedAttributes = ['src'];
attributeChangedCallback(name, oldValue, newValue) {
if (name !== 'src') {
return;
}
this.src = newValue;
unregisterPageScriptElement(oldValue);
registerPageScriptElement(newValue);
}
disconnectedCallback() {
unregisterPageScriptElement(this.src);
}
});
blazor.addEventListener('enhancedload', onEnhancedLoad);
}
Di RCL, tambahkan komponen berikut PageScript
.
PageScript.razor
:
<page-script src="@Src"></page-script>
@code {
[Parameter]
[EditorRequired]
public string Src { get; set; } = default!;
}
Komponen PageScript
biasanya berfungsi pada tingkat atas halaman.
Jika Anda menempatkan PageScript
komponen dalam tata letak aplikasi (misalnya, MainLayout.razor
), yang menghasilkan dibagikan PageScript
di antara halaman yang menggunakan tata letak, maka komponen hanya berjalan onLoad
setelah pemuatan ulang halaman penuh dan onUpdate
ketika pembaruan halaman yang ditingkatkan terjadi, termasuk navigasi yang ditingkatkan.
Untuk menggunakan kembali modul yang sama di antara halaman, tetapi meminta onLoad
panggilan balik dan onDispose
pada setiap perubahan halaman, tambahkan string kueri ke akhir skrip sehingga dikenali sebagai modul yang berbeda. Aplikasi dapat mengadopsi konvensi penggunaan nama komponen sebagai nilai string kueri. Dalam contoh berikut, string kueri adalah "counter
" karena referensi komponen ini PageScript
ditempatkan dalam komponen Counter
. Ini hanyalah saran, dan Anda dapat menggunakan skema string kueri apa pun yang Anda sukai.
<PageScript Src="./Components/Pages/PageWithScript.razor.js?counter" />
Untuk memantau perubahan dalam elemen DOM tertentu, gunakan MutationObserver
pola di JS pada klien. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).
Contoh implementasi tanpa menggunakan RCL
Pendekatan yang dijelaskan dalam artikel ini dapat diimplementasikan langsung dalam Blazor Web App tanpa menggunakan Razor pustaka kelas (RCL). Misalnya, lihat Mengaktifkan pembuatan kode QR untuk aplikasi pengautentikasi TOTP di ASP.NET Core Blazor Web App.
ASP.NET Core