ASP.NET Core Blazor JavaScript se statickým vykreslováním na straně serveru (statické SSR)
Tento článek vysvětluje, jak načíst JavaScript (JS) ve Blazor webové aplikaci se statickým vykreslováním na straně serveru (statická služba SSR) a vylepšenou navigaci.
Některé aplikace závisí na JS provádění inicializačních úloh, které jsou specifické pro každou stránku. Pokud používáte Blazorfunkci rozšířené navigace, která uživateli umožňuje vyhnout se opětovnému načtení celé stránky, nemusí být znovu spuštěna podle JS očekávání pokaždé, když dojde k rozšířené navigaci na stránce.
Abychom se tomuto problému vyhnuli, nedoporučujeme spoléhat se na prvky specifické pro <script>
stránku umístěné mimo soubor rozložení použitý pro danou komponentu. Místo toho by skripty měly zaregistrovat afterWebStarted
JS inicializátor pro provádění logiky inicializace a používat naslouchací proces událostí (blazor.addEventListener("enhancedload", callback)
) k naslouchání aktualizacím stránek způsobeným vylepšenou navigací.
Následující příklad ukazuje jeden ze způsobů, jak nakonfigurovat JS kód, který se má spustit, když je na začátku načtena nebo aktualizována staticky vykreslená stránka s vylepšenou navigaci.
Následující PageWithScript
příklad komponenty je komponenta v aplikaci, která vyžaduje, aby se skripty spouštěly se statickým prostředím SSR a vylepšenou navigaci. Následující příklad komponenty obsahuje komponentu PageScript
Razor z knihovny tříd (RCL), která je přidána do řešení dále v tomto článku.
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 Do webové aplikace přidejte následující kompletovaný JS soubor:
onLoad
je volána při přidání skriptu na stránku.onUpdate
je volána, pokud skript stále existuje na stránce po rozšířené aktualizaci.onDispose
je volána při odebrání skriptu ze stránky po rozšířené aktualizaci.
Components/Pages/PageWithScript.razor.js
:
export function onLoad() {
console.log('Loaded');
}
export function onUpdate() {
console.log('Updated');
}
export function onDispose() {
console.log('Disposed');
}
V knihovně Razor tříd (RCL) (příklad RCL je pojmenován BlazorPageScript
) přidejte následující modul.
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);
}
Do seznamu RCL přidejte následující PageScript
komponentu.
PageScript.razor
:
<page-script src="@Src"></page-script>
@code {
[Parameter]
[EditorRequired]
public string Src { get; set; } = default!;
}
Komponenta PageScript
funguje normálně na nejvyšší úrovni stránky.
Pokud komponentu PageScript
umístíte do rozložení aplikace (například MainLayout.razor
), což vede ke sdílení PageScript
mezi stránkami, které toto rozložení používají, pak se komponenta spustí onLoad
až po opětovném načtení celé stránky a onUpdate
při jakékoli rozšířené aktualizaci stránky, včetně rozšířené navigace.
Pokud chcete použít stejný modul mezi stránkami, ale při onLoad
každé změně stránky se vyvolá a onDispose
zpětná volání, připojte na konec skriptu řetězec dotazu, aby byl rozpoznán jako jiný modul. Aplikace může přijmout konvenci použití názvu komponenty jako řetězcové hodnoty dotazu. V následujícím příkladu je řetězec dotazu "counter
", protože tento PageScript
odkaz na komponentu Counter
je umístěn. Jedná se pouze o návrh a můžete použít libovolné schéma řetězce dotazu, které dáváte přednost.
<PageScript Src="./Components/Pages/PageWithScript.razor.js?counter" />
Pokud chcete monitorovat změny v konkrétních prvčtech MODELU DOM, použijte MutationObserver
vzor v JS klientovi. Další informace najdete v tématu ASP.NET Interoperabilita Core Blazor JavaScriptu (JSinteroperabilita).
Příklad implementace bez použití seznamu RCL
Přístup popsaný v tomto článku lze implementovat přímo ve Blazor webové aplikaci bez použití Razor knihovny tříd (RCL). Příklad najdete v tématu Povolení generování kódu QR pro ověřovací aplikace TOTP ve webové aplikaci ASP.NET CoreBlazor.