Delen via


JavaScript-locatie in ASP.NET Core Blazor-apps

Notitie

Dit is niet de nieuwste versie van dit artikel. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Waarschuwing

Deze versie van ASP.NET Core wordt niet meer ondersteund. Zie de .NET- en .NET Core-ondersteuningsbeleidvoor meer informatie. Zie de .NET 9-versie van dit artikelvoor de huidige release.

Belangrijk

Deze informatie heeft betrekking op een pre-releaseproduct dat aanzienlijk kan worden gewijzigd voordat het commercieel wordt uitgebracht. Microsoft geeft geen garanties, uitdrukkelijk of impliciet, met betrekking tot de informatie die hier wordt verstrekt.

Zie de .NET 9-versie van dit artikelvoor de huidige release.

Laad JavaScript-code (JS) met behulp van een van de volgende benaderingen:

Inline JavaScript wordt niet aanbevolen voor Blazor apps. We raden u aan JS collocatie te gebruiken in combinatie met JS modules.

Locatie van <script> tags

Plaats alleen een <script> tag in een onderdeelbestand (.razor) als het onderdeel gegarandeerd statische SSR-rendering (statische SSR) omdat de <script> tag niet dynamisch kan worden bijgewerkt. Als u een <script> tag in een onderdeelbestand plaatst, wordt er geen waarschuwing of fout over de compilatietijd gegenereerd, maar het laadgedrag van scripts komt mogelijk niet overeen met uw verwachtingen in onderdelen die geen statische SSR gebruiken wanneer het onderdeel wordt weergegeven.

Plaats geen <script> tag in een onderdeelbestand (.razor) omdat de tag <script> niet dynamisch kan worden bijgewerkt. Het plaatsen van een <script> tag in een onderdeelbestand produceert een compilatiefout.

Notitie

Documentatievoorbeelden plaatsen meestal scripts in een <script> tag of laden globale scripts uit externe bestanden. Deze benaderingen vervuilen de klant met wereldwijde functies. Voor productie-apps raden we u aan JS in afzonderlijke JS modules te plaatsen die kunnen worden geïmporteerd wanneer dat nodig is. Zie de sectie JavaScript-isolatie in JavaScript-modules voor meer informatie.

Notitie

Documentatievoorbeelden plaatsen scripts in een <script> tag of laden globale scripts uit externe bestanden. Deze benaderingen vervuilen de klant met wereldwijde functies. Het plaatsen van JS in afzonderlijke JS modules die kunnen worden geïmporteerd wanneer dat nodig is, wordt niet ondersteund in Blazor ouder dan ASP.NET Core 5.0. Als voor de app het gebruik van JS modules voor JS isolatie is vereist, raden we u aan ASP.NET Core 5.0 of hoger te gebruiken om de app te bouwen. Voor meer informatie gebruikt u de vervolgkeuzelijst versie om een 5.0 of nieuwere versie van dit artikel te selecteren. Zie de JavaScript-isolatie in JavaScript-modules sectie.

Een script laden in <head> opmaak

De benadering in deze sectie wordt doorgaans niet aanbevolen.

Plaats de JavaScript-tags (JS) (<script>...</script>) in de <head> elementmarkeringen:

<head>
    ...

    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</head>

Het laden van JS vanuit de <head> is om de volgende redenen niet de beste methode:

  • JS interop kan mislukken als het script afhankelijk is van Blazor. We raden u aan scripts te laden met een van de andere benaderingen, niet via de <head> markeringen.
  • De pagina kan interactief langzamer worden vanwege de tijd die nodig is om de JS in het script te parseren.

In onderdeelmarkeringen kunnen scripts worden geladen via een HeadContent onderdeel, met het gebruikelijke voorbehoud dat deze benadering de laadtijd van de pagina aan de clientzijde vertraagt, wat we aanraden te vermijden. Wanneer een script wordt geladen met een HeadContent-onderdeel in een Blazor Server-app, Blazor WebAssembly-app of een Blazor Web App met behulp van een interactieve weergavemodus (interactieve SSR, client-side rendering (CSR)), wordt bij het navigeren weg van de pagina van de component de <script>-tag verwijderd uit de weergegeven <head>-inhoud, maar wordt de JavaScript-code van het script niet ontladen, inclusief gebeurtenishandlers die door het script worden geregistreerd, en de variabelen en methoden die het script biedt. Alleen Blazor Web App's met statische SSR ontladen JavaScript-code wanneer de gebruiker de pagina verlaat. Over het algemeen kunt u beter <script>-tags toevoegen aan de fysieke <head>-inhoud, tenzij u expliciet dergelijke scriptverwijzingen in de onderdelen wilt bewaren die deze gebruiken en het niet erg vindt dat de code bij navigatiegebeurtenissen niet wordt ontladen.

In componentmarkeringen kunnen scripts worden geladen via een HeadContent onderdeel met het gebruikelijke voorbehoud dat de benadering de laadtijd van de pagina op de client vertraagt, wat we aanraden te vermijden. Wanneer een script wordt geladen met een HeadContent-onderdeel, wordt door het navigeren weg van de pagina van het onderdeel de <script> tag verwijderd uit de gerenderde <head> inhoud, maar wordt de JavaScript-code van het script niet verwijderd, inclusief de door het script geregistreerde gebeurtenishandlers, blootgestelde variabelen en methoden die het script biedt. Over het algemeen kunt u beter <script> tags aan de fysieke <head>-inhoud toevoegen, tenzij u expliciet dergelijke scriptverwijzingen wilt bewaren in de onderdelen die deze gebruiken en het niet erg vindt dat de code niet wordt ontladen bij navigatiegebeurtenissen.

Een script laden in <body> opmaak

Plaats de JavaScript-tags (<script>...</script>) in het </body> element sluiten na de Blazor scriptreferentie:

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</body>

In het voorgaande voorbeeld is de tijdelijke aanduiding {BLAZOR SCRIPT} het Blazor scriptpad en de bestandsnaam. Zie ASP.NET Core Blazor projectstructuurvoor de locatie van het script.

Een script laden vanuit een extern JavaScript-bestand (.js) dat is geplaatst met een onderdeel

Collocation van JavaScript-bestanden (JS) voor Razor onderdelen is een handige manier om scripts in een app te organiseren.

Razor componenten van Blazor apps ordenen JS bestanden met behulp van de .razor.js-extensie en zijn openbaar toegankelijk via het pad naar het bestand in het project:

{PATH}/{COMPONENT}.razor.js

  • De tijdelijke aanduiding {PATH} is het pad naar het onderdeel.
  • De tijdelijke aanduiding {COMPONENT} is het onderdeel.

Wanneer de app wordt gepubliceerd, verplaatst het framework het script automatisch naar de webroot. Scripts worden verplaatst naar bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js, waarbij de tijdelijke aanduidingen zijn:

  • {TARGET FRAMEWORK MONIKER} is de Target Framework Moniker (TFM).
  • {PATH} is het pad naar het onderdeel.
  • {COMPONENT} is de naam van het onderdeel.

Er is geen wijziging vereist voor de relatieve URL van het script, omdat Blazor het JS bestand in gepubliceerde statische assets voor u plaatst.

Deze sectie en de volgende voorbeelden zijn voornamelijk gericht op het uitleggen van JS bestands collocatie. In het eerste voorbeeld ziet u een samen geplaatst JS-bestand met een gewone JS-functie. In het tweede voorbeeld ziet u hoe een module wordt gebruikt om een functie te laden. Dit is de aanbevolen benadering voor de meeste productie-apps. Het aanroepen van JS vanuit .NET wordt volledig behandeld in JavaScript-functies aanroepen vanuit .NET-methoden in ASP.NET Core Blazor, waar de BlazorJS-API verder wordt uitgelegd met aanvullende voorbeelden. De verwijdering van onderdelen, die in het tweede voorbeeld aanwezig is, wordt behandeld in ASP.NET levenscyclus van Razor onderdelen.

Met het volgende JsCollocation1 onderdeel wordt een script geladen via een HeadContent-onderdeel en wordt een JS-functie aangeroepen met IJSRuntime.InvokeAsync. De tijdelijke aanduiding {PATH} is het pad naar het onderdeel.

Belangrijk

Als u de volgende code gebruikt voor een demonstratie in een test-app, wijzigt u de tijdelijke aanduiding {PATH} in het pad van het onderdeel (bijvoorbeeld: Components/Pages in .NET 8 of hoger of Pages in .NET 7 of eerder). In een Blazor Web App (.NET 8 of hoger) vereist het onderdeel een interactieve weergavemodus die globaal is toegepast op de app of op de definitie van het onderdeel.

Voeg het volgende script toe na het Blazor script (locatie van het Blazor startscript):

<script src="{PATH}/JsCollocation1.razor.js"></script>

JsCollocation1 onderdeel ({PATH}/JsCollocation1.razor):

@page "/js-collocation-1"
@inject IJSRuntime JS

<PageTitle>JS Collocation 1</PageTitle>

<h1>JS Collocation Example 1</h1>

<button @onclick="ShowPrompt">Call showPrompt1</button>

@if (!string.IsNullOrEmpty(result))
{
    <p>
        Hello @result!
    </p>
}

@code {
    private string? result;

    public async Task ShowPrompt()
    {
        result = await JS.InvokeAsync<string>(
            "showPrompt1", "What's your name?");
        StateHasChanged();
    }
}

Het JS-bestand wordt naast het JsCollocation1 onderdeelbestand geplaatst met de bestandsnaam JsCollocation1.razor.js. In het JsCollocation1-onderdeel wordt naar het script verwezen op het pad van het collocated-bestand. In het volgende voorbeeld accepteert de functie showPrompt1 de naam van de gebruiker van een Window prompt() en retourneert deze naar het JsCollocation1 onderdeel voor weergave.

{PATH}/JsCollocation1.razor.js:

function showPrompt1(message) {
  return prompt(message, 'Type your name here');
}

De voorgaande benadering wordt niet aanbevolen voor algemeen gebruik in productie-apps, omdat de benadering de client vervuilt met globale functies. Een betere benadering voor productie-apps is het gebruik van JS modules. Dezelfde algemene principes zijn van toepassing op het laden van een JS-module uit een JS-bestand, zoals in het volgende voorbeeld wordt gedemonstreerde.

Met de JsCollocation2 methode van het volgende OnAfterRenderAsync onderdeel wordt een JS module in modulegeladen. Dit is een IJSObjectReference van de onderdeelklasse. module wordt gebruikt om de functie showPrompt2 aan te roepen. De tijdelijke aanduiding {PATH} is het pad naar het onderdeel.

Belangrijk

Als u de volgende code gebruikt voor een demonstratie in een test-app, wijzigt u de tijdelijke aanduiding {PATH} in het pad van het onderdeel. In een Blazor Web App (.NET 8 of hoger) vereist het onderdeel een interactieve weergavemodus die globaal is toegepast op de app of op de definitie van het onderdeel.

JsCollocation2 onderdeel ({PATH}/JsCollocation2.razor):

@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>JS Collocation 2</PageTitle>

<h1>JS Collocation Example 2</h1>

<button @onclick="ShowPrompt">Call showPrompt2</button>

@if (!string.IsNullOrEmpty(result))
{
    <p>
        Hello @result!
    </p>
}

@code {
    private IJSObjectReference? module;
    private string? result;

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            /*
                Change the {PATH} placeholder in the next line to the path of
                the collocated JS file in the app. Examples:

                ./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
                ./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
            */
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./{PATH}/JsCollocation2.razor.js");
        }
    }

    public async void ShowPrompt()
    {
        if (module is not null)
        {
            result = await module.InvokeAsync<string>(
                "showPrompt2", "What's your name?");
            StateHasChanged();
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (module is not null)
        {
            try
            {
                await module.DisposeAsync();
            }
            catch (JSDisconnectedException)
            {
            }
        }
    }
}

In het voorgaande voorbeeld raakt JSDisconnectedException opgesloten tijdens het verwijderen van de module als het Blazor-circuit van SignalRuitvalt. Als de voorgaande code wordt gebruikt in een Blazor WebAssembly-app, is er geen SignalR verbinding om te verliezen, zodat u het try-catch blok kunt verwijderen en de regel kunt laten staan waarmee de module (await module.DisposeAsync();) wordt vrijgegeven. Zie ASP.NET Core Blazor JavaScript-interoperabiliteit (JS interop)voor meer informatie.

{PATH}/JsCollocation2.razor.js:

export function showPrompt2(message) {
  return prompt(message, 'Type your name here');
}

Belangrijk

Plaats geen <script> tag voor JsCollocation2.razor.js na het Blazor script omdat de module automatisch wordt geladen en in de cache wordt opgeslagen wanneer de dynamische import() wordt aangeroepen.

Het gebruik van scripts en modules voor JS in een Razor klassebibliotheek (RCL) wordt alleen ondersteund voor het Blazor-interopmechanisme van JS, gebaseerd op de IJSRuntime-interface. Als u JavaScript [JSImport]/[JSExport] interopimplementeert, raadpleegt u JavaScript JSImport/JSExport-interop met ASP.NET Core Blazor.

Voor scripts of modules geleverd door een Razor klassebibliotheek (RCL) die IJSRuntime-gebaseerde JS-interoperabiliteit gebruikt, wordt het volgende pad gebruikt:

./_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js

  • Het padsegment voor de huidige map (./) is vereist om het juiste pad voor statische bestanden naar het JS-bestand op te stellen.
  • De tijdelijke aanduiding {PACKAGE ID} is de pakket-id van de RCL (of bibliotheeknaam voor een klassebibliotheek waarnaar wordt verwezen door de app).
  • De tijdelijke aanduiding {PATH} is het pad naar het onderdeel. Als een Razor component zich in de root van de RCL bevindt, wordt het padsegment niet opgenomen.
  • De tijdelijke aanduiding {COMPONENT} is de naam van het onderdeel.
  • De plaatsaanduiding voor {EXTENSION} komt overeen met de extensie van het onderdeel, ofwel razor of cshtml.

In het volgende Blazor app-voorbeeld:

  • De pakket-id van de RCL is AppJS.
  • De scripts van een module worden geladen voor het JsCollocation3-onderdeel (JsCollocation3.razor).
  • Het JsCollocation3 onderdeel bevindt zich in de map Components/Pages van de RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import", 
    "./_content/AppJS/Components/Pages/JsCollocation3.razor.js");

Voor meer informatie over RCL's, zie Consume ASP.NET Core Razor-componenten vanuit een Razor classbibliotheek (RCL).

Een script laden vanuit een extern JavaScript-bestand (.js)

Plaats de JavaScript-tags () (), met een pad naar de scriptbron (), binnen het afsluitende -element () van de , na de verwijzing naar het script ():

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

Voor de plaatsaanduidingen in het voorgaande voorbeeld:

  • De plaatsaanduiding {BLAZOR SCRIPT} is het pad en de bestandsnaam van het script Blazor. Zie ASP.NET Core Blazor projectstructuurvoor de locatie van het script.
  • De plaatsaanduiding {SCRIPT PATH AND FILE NAME (.js)} is het pad en de naam van het scriptbestand onder wwwroot.

In het volgende voorbeeld van de voorgaande <script> tag bevindt het scripts.js bestand zich in de map wwwroot/js van de app:

<script src="js/scripts.js"></script>

U kunt scripts ook direct vanuit de wwwroot map draaien als u ervoor kiest uw scripts niet in een aparte map onder wwwrootte plaatsen.

<script src="scripts.js"></script>

Wanneer het externe JS-bestand wordt geleverd door een -Razor-class library, specificeert u het JS-bestand met behulp van het stabiele statische web-assetpad: _content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}:

  • De tijdelijke aanduiding {PACKAGE ID} is de pakket-ID van de bibliotheek. De pakket-id wordt standaard ingesteld op de assemblynaam van het project als <PackageId> niet is opgegeven in het projectbestand.
  • De placeholder {SCRIPT PATH AND FILE NAME (.js)} is het pad en de bestandsnaam bij wwwroot.
<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

In het volgende voorbeeld van de voorgaande <script> tag:

  • De Razor classbibliotheek heeft de assemblynaam ComponentLibrary, en er is geen <PackageId> opgegeven in het projectbestand van de bibliotheek.
  • Het bestand scripts.js bevindt zich in de wwwroot map van de klassebibliotheek.
<script src="_content/ComponentLibrary/scripts.js"></script>

Zie ASP.NET Core Razor-onderdelen van een Razor klassebibliotheek (RCL) gebruikenvoor meer informatie.

Een script vóór of na het starten van Blazor injecteren

Gebruik een JavaScript-initialisatiefunctie om ervoor te zorgen dat scripts worden geladen voor of nadat Blazor wordt gestart. Zie ASP.NET Core Blazor startupvoor meer informatie en voorbeelden.

Een script injecteren nadat Blazor is gestart

Als u een script wilt injecteren nadat Blazor is gestart, verbind deze met de Promise die voortkomt uit een handmatig begin van Blazor. Zie ASP.NET Core Blazor startupvoor meer informatie en een voorbeeld.

JavaScript-isolatie in JavaScript-modules

Blazor maakt isolatie van JavaScript (JS) mogelijk in standaard JS modules (ECMAScript-specificatie).

JS isolatie biedt de volgende voordelen:

  • Geïmporteerde JS vervuilt de globale naamruimte niet meer.
  • Gebruikers van een bibliotheek en componenten hoeven de gerelateerde JSniet te importeren.

In scenario's aan de serverzijde onderschept u altijd JSDisconnectedException in het geval verlies van het BlazorSignalR circuit voorkomt dat een JS interop-aanroep een module disposeert, resulterend in een niet-afgehandelde uitzondering. De Blazor WebAssembly-apps gebruiken geen SignalR-verbinding tijdens JS-interoperabiliteit, dus hoeft u JSDisconnectedException niet op te vangen in Blazor WebAssembly-apps voor het verwijderen van modules.

Zie de volgende bronnen voor meer informatie: