JavaScript-samverkan med Blazor
- 5 minuter
Blazor använder C#-komponenter i stället för JavaScript för att skapa webbsidor eller HTML-avsnitt med dynamiskt innehåll. Men du kan använda Blazor JavaScript-samverkan (JS interop) för att anropa JavaScript-bibliotek i Blazor-appar och anropa JavaScript-funktioner från .NET C#-kod.
I den här lektionen lär du dig att anropa JavaScript från C#-kod på en Blazor-sida och hur du anropar C#-metoder från JavaScript-funktioner. I nästa lektion använder du en aviseringskomponent från ett JavaScript-bibliotek för att uppdatera blazor-pizzaleveranswebbplatsen.
Använda Blazor JavaScript-samverkan
En typisk Blazor-komponent använder layout- och användargränssnittslogik för att återge HTML vid körning. Du använder C#-kod för att hantera händelser och andra dynamiska sidfunktioner som interagerar med användaren och externa tjänster. I många fall behöver du inte använda JavaScript-kod. I stället kan du använda Blazor med .NET-bibliotek, vilket ger många motsvarande funktioner.
Ibland behöver du dock använda ett befintligt JavaScript-bibliotek. Till exempel renderar vissa JavaScript-bibliotek med öppen källkod komponenter och hanterar användargränssnittselement på ett specialiserat sätt. Du kan också ha befintlig testad JavaScript-kod som du vill återanvända i stället för att konvertera den till C#.
Du kan integrera JavaScript-bibliotek i dina program med hjälp av Blazor JavaScript-samverkan eller JS-interop. Du använder JS-interop för att anropa JavaScript-funktioner från .NET-metoder och för att anropa .NET-metoder från JavaScript-funktioner. JS-interop hanterar marshaling av data- och objektreferenser mellan Blazor och JavaScript för att underlätta övergången mellan dem.
Läsa in JavaScript-kod i en Blazor-app
Du lägger till JavaScript i en Blazor-app på samma sätt som du lägger till den i en HTML-standardwebbapp med hjälp av HTML-elementet <script> . Du lägger till taggen <script> efter den befintliga <script src="_framework/blazor.*.js"></script> taggen i antingen filen Pages/_Host.cshtml eller filen wwwroot/index.html , beroende på din Blazor-värdmodell. Mer information finns i ASP.NET Core Blazor-värdmodeller.
Det är bäst att inte placera skript i elementet <head> på sidan. Blazor styr endast innehållet i elementet <body> på en HTML-sida, så JS-interop kan misslyckas om skripten är beroende av Blazor. Sidan kan också visas långsammare på grund av den tid det tar att parsa JavaScript-koden.
Taggen <script> fungerar som den gör i en HTML-webbapp. Du kan skriva kod direkt i taggens brödtext eller referera till en befintlig JavaScript-fil. Mer information finns i ASP.NET Core Blazor JavaScript-interoperabilitet (JS interop): JavaScript-lokalisering.
Viktigt!
Placera JavaScript-filer under mappen wwwroot i ditt Blazor-projekt.
Ett annat alternativ är att mata in elementet <script> som refererar till en JavaScript-fil till sidan Pages/_Host.cshtml dynamiskt. Den här metoden är användbar om du behöver läsa in olika skript beroende på villkor som endast kan fastställas vid körning. Den här metoden kan också påskynda den första inläsningen av appen om du utlöser logiken med en händelse som utlöses när en sida återges. Mer information finns i ASP.NET Core Blazor-start.
Anropa JavaScript från .NET-kod
Du använder IJSRuntime för att anropa en JavaScript-funktion från .NET-kod. För att göra JS interop-körningen tillgänglig matar du in en instans av abstraktionen IJSRuntime på en Blazor-sida efter @page direktivet nära början av filen.
Gränssnittet IJSRuntime exponerar InvokeAsync metoderna och InvokeVoidAsync för att anropa JavaScript-kod. Använd InvokeAsync<TValue> för att anropa en JavaScript-funktion som returnerar ett värde. Annars anropar du InvokeVoidAsync. Som namnen antyder är båda metoderna asynkrona, så du använder C# await -operatorn för att samla in resultat.
Parametern till InvokeAsync metoden eller InvokeVoidAsync är namnet på den JavaScript-funktion som ska anropas, följt av argument som funktionen kräver. JavaScript-funktionen måste vara en del av omfånget window eller ett underscope för window. Argumenten måste vara JSON-serialiserbara.
Kommentar
JS-interop är endast tillgängligt när en SignalR-anslutning upprättas mellan Blazor Server-appen och webbläsaren. Du kan inte göra interop-anrop förrän renderingen är klar. Om du vill identifiera om renderingen är klar, använder du OnAfterRender- eller OnAfterRenderAsync-händelsen i din Blazor-kod.
Använda ett ElementReference-objekt för att uppdatera DOM
Blazor upprätthåller en representation av dokumentobjektmodellen (DOM) som ett virtuellt återgivningsträd. När sidstrukturen ändras genererar Blazor ett nytt återgivningsträd som innehåller skillnaderna. När ändringarna är klara itererar Blazor genom skillnaderna för att uppdatera webbläsarvisningen av användargränssnittet och webbläsarversionen av DOM som JavaScript använder.
Många JavaScript-bibliotek från tredje part är tillgängliga för återgivning av element på en sida, och dessa bibliotek kan uppdatera DOM. Om JavaScript-koden ändrar elementen i DOM kanske Blazor-kopian av DOM inte längre matchar det aktuella tillståndet. Den här situationen kan orsaka oväntat beteende och eventuellt medföra säkerhetsrisker. Det är viktigt att inte göra ändringar som kan leda till att Blazor-vyn för DOM blir skadad.
Det enklaste sättet att hantera den här situationen är att skapa ett platshållarelement i Blazor-komponenten, vanligtvis ett tomt <div @ref="placeHolder"></div> element. Blazor-koden tolkar den här koden som ett tomt utrymme och Blazor-återgivningsträdet försöker inte spåra innehållet. Du kan fritt lägga till JavaScript-kodelement i detta <div>, och Blazor försöker inte ändra det.
Blazor-appkod definierar ett fält av typen ElementReference som innehåller referensen till elementet <div> . Attributet @ref för elementet <div> anger värdet för fältet. Objektet ElementReference skickas sedan till en JavaScript-funktion, som kan använda referensen för att lägga till innehåll i elementet <div> .
Anropa .NET-kod från JavaScript
JavaScript-kod kan köra en .NET-metod som din Blazor-kod definierar med hjälp av verktygsklassen DotNet , som är en del av JS-interopbiblioteket. Klassen DotNet exponerar hjälpfunktionerna invokeMethod och invokeMethodAsync . Använd invokeMethod för att köra en metod och vänta på resultatet, eller använd invokeMethodAsync för att anropa metoden asynkront. Metoden invokeMethodAsync returnerar ett JavaScript Promise.
Dricks
Om du vill behålla svarstiden i dina program definierar du .NET-metoden som asyncoch anropar den med hjälp invokeMethodAsync av från JavaScript.
Du måste tagga .NET-metoden som anropas med JSInvokableAttribute. Metoden måste vara public, och alla parametrar måste vara JSON-serializable. För en asynkron metod måste returtypen också vara void, ett Taskeller ett allmänt Task<T> objekt där T är en JSON-serialiserbar typ.
Om du vill anropa en static metod anger du namnet på den .NET-sammansättning som innehåller klassen, en identifierare för metoden och eventuella parametrar som metoden accepterar som argument för invokeMethod eller invokeMethodAsync -funktionerna. Som standard är metodidentifieraren samma som namnet på metoden, men du kan ange ett annat värde med hjälp JSInvokable av attributet.
Anropa en .NET-instansmetod från JavaScript
För att köra en instansmetod kräver JavaScript en objektreferens som pekar på instansen. JS-interop tillhandahåller den generiska DotNetObjectReference typ som du kan använda för att skapa en objektreferens i .NET-kod. Koden måste göra den här objektreferensen tillgänglig för JavaScript.
JavaScript-koden kan sedan anropa invokeMethodAsync med namnet på .NET-metoden och alla parametrar som metoden kräver. För att undvika minnesläckor bör .NET-koden ta bort objektreferensen när den inte längre behövs.