ASP.NET Core Blazor JavaScript ze statycznym renderowaniem po stronie serwera (statyczne SSR)
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
W tym artykule wyjaśniono, jak załadować kod JavaScript (JS) w programie Blazor Web App ze statycznym renderowaniem po stronie serwera (static SSR) i rozszerzonymi nawigacjami.
Niektóre aplikacje zależą od JS wykonywania zadań inicjowania specyficznych dla każdej strony. W przypadku korzystania z Blazorrozszerzonej funkcji nawigacji, która pozwala użytkownikowi uniknąć ponownego ładowania całej strony, szczegółowe informacje dotyczące JS strony mogą nie być wykonywane ponownie zgodnie z oczekiwaniami za każdym razem, gdy wystąpi ulepszona nawigacja po stronie.
Aby uniknąć tego problemu, nie zalecamy polegania na elementach specyficznych dla <script>
strony umieszczonych poza plikiem układu zastosowanym do składnika. Zamiast tego skrypty powinny zarejestrować afterWebStarted
JS inicjator do wykonywania logiki inicjowania i używać odbiornika zdarzeń (blazor.addEventListener("enhancedload", callback)
) do nasłuchiwania aktualizacji stron spowodowanych przez rozszerzoną nawigację.
W poniższym przykładzie pokazano jeden ze sposobów konfigurowania JS kodu do uruchomienia, gdy statycznie renderowana strona z rozszerzonym nawigacją jest początkowo ładowana lub aktualizowana.
Poniższy PageWithScript
przykładowy składnik to składnik w aplikacji, który wymaga uruchamiania skryptów przy użyciu statycznego przewodnika SSR i rozszerzonej nawigacji. Poniższy przykład składnika zawiera PageScript
składnik z Razor biblioteki klas (RCL), który jest dodawany do rozwiązania w dalszej części tego artykułu.
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.
W pliku Blazor Web Appdodaj następujący collocated JS plik:
onLoad
jest wywoływany po dodaniu skryptu do strony.onUpdate
jest wywoływany, gdy skrypt nadal istnieje na stronie po rozszerzonej aktualizacji.onDispose
jest wywoływany po usunięciu skryptu ze strony po rozszerzonej aktualizacji.
Components/Pages/PageWithScript.razor.js
:
export function onLoad() {
console.log('Loaded');
}
export function onUpdate() {
console.log('Updated');
}
export function onDispose() {
console.log('Disposed');
}
W bibliotece Razor klas (RCL) (przykładowa lista RCL nosi nazwę BlazorPageScript
), dodaj następujący moduł.
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);
}
Na liście RCL dodaj następujący PageScript
składnik.
PageScript.razor
:
<page-script src="@Src"></page-script>
@code {
[Parameter]
[EditorRequired]
public string Src { get; set; } = default!;
}
Składnik PageScript
działa normalnie na najwyższym poziomie strony.
Jeśli umieścisz PageScript
składnik w układzie aplikacji (na przykład MainLayout.razor
), co spowoduje udostępnienie PageScript
go między stronami korzystającymi z układu, składnik jest uruchamiany onLoad
tylko po ponownym załadowaniu pełnej strony i onUpdate
w przypadku wystąpienia dowolnej rozszerzonej aktualizacji strony, w tym rozszerzonej nawigacji.
Aby ponownie użyć tego samego modułu między stronami, ale wywołania onLoad
zwrotne i onDispose
są wywoływane na każdej stronie, dołącz ciąg zapytania na końcu skryptu, aby był rozpoznawany jako inny moduł. Aplikacja może przyjąć konwencję używania nazwy składnika jako wartości ciągu zapytania. W poniższym przykładzie ciąg zapytania to "counter
", ponieważ odwołanie do tego PageScript
składnika jest umieszczone w składniku Counter
. Jest to tylko sugestia i można użyć dowolnego preferowanego schematu ciągów zapytania.
<PageScript Src="./Components/Pages/PageWithScript.razor.js?counter" />
Aby monitorować zmiany w określonych elementach DOM, należy użyć MutationObserver
wzorca w JS kliencie. Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).
Przykładowa implementacja bez używania listy RCL
Podejście opisane w tym artykule można zaimplementować bezpośrednio w obiekcie Blazor Web App bez użycia Razor biblioteki klas (RCL). Aby zapoznać się z przykładem, zobacz Włączanie generowania kodu QR dla aplikacji uwierzytelniającego TOTP w ASP.NET Core Blazor Web App.