ASP.NET Core Blazor JavaScript se statickým vykreslováním na straně serveru (statické SSR)
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek vysvětluje, jak načíst JavaScript (JS) do Blazor Web App vykreslování na straně statického serveru (static 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 k provádění logiky inicializace a používat posluchač událostí k čekání na aktualizace stránek způsobené vylepšenou navigací.
Dění
V následujících příkladech naslouchacího procesu událostí je zástupný symbol {CALLBACK}
funkce zpětného volání.
Rozšířené spuštění navigace (
enhancednavigationstart
) aktivuje zpětné volání dříve, než dojde k rozšířené navigaci:blazor.addEventListener("enhancednavigationstart", {CALLBACK});
Vylepšený navigační konec (
enhancednavigationend
) aktivuje zpětné volání po rozšířené navigaci:blazor.addEventListener("enhancednavigationend", {CALLBACK});
Rozšířené načítání navigační stránky (
enhancedload
) vyvolá zpětné volání pokaždé, když se stránka aktualizuje z důvodu rozšířené navigace, včetně aktualizací streamu :blazor.addEventListener("enhancedload", {CALLBACK});
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 k provádění logiky inicializace a používat naslouchací objekt k naslouchání aktualizacím stránek způsobeným zlepšenou navigací.
blazor.addEventListener("enhancedload", {CALLBACK});
V předchozím příkladu je zástupný symbol {CALLBACK}
funkcí zpětného volání.
Příklad rozšířeného skriptu načtení stránky
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.
Do pole Blazor Web Apppř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 v Blazor Web App 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 v ASP.NET Core Blazor Web App.