JavaScript-Interoperabilität mit Blazor

Abgeschlossen

Blazor verwendet C#-Komponenten anstelle von JavaScript, um Webseiten oder HTML-Abschnitte mit dynamischem Inhalt zu erstellen. Sie können jedoch Blazor-JavaScript-Interoperabilität (JS-Interop) verwenden, um JavaScript-Bibliotheken in Blazor-Apps aufzurufen und JavaScript-Funktionen aus .NET C#-Code aufzurufen.

In dieser Einheit lernen Sie, wie Sie JavaScript aus C#-Code auf einer Blazor-Seite und C#-Methoden über JavaScript-Funktionen aufrufen. In der nächsten Einheit verwenden Sie eine Warnungskomponente aus einer JavaScript-Bibliothek, um Ihre Blazor-Pizzalieferwebsite zu aktualisieren.

Verwenden der Blazor-JavaScript-Interoperabilität

Eine typische Blazor-Komponente enthält eine Layout- und Benutzeroberflächenlogik, die für das Rendern von HTML zur Laufzeit verwendet wird. Sie verwenden C#-Code, um Ereignisse und andere dynamische Seitenfeatures zu behandeln, die mit Benutzer*innen und externen Diensten interagieren. In vielen Fällen müssen Sie keinen JavaScript-Code verwenden. Stattdessen können Sie Blazor mit .NET-Bibliotheken verwenden, die viele gleichwertige Funktionen bieten.

Manchmal müssen Sie jedoch eine vorhandene JavaScript-Bibliothek verwenden. Beispielsweise führen einige Open-Source-JavaScript-Bibliotheken das Rendern von Komponenten und die Verarbeitung von Elementen der Benutzeroberfläche in spezieller Weise durch. Möglicherweise verfügen Sie auch über vorhandenen, getesteten JavaScript-Code, den Sie wiederverwenden möchten, anstatt ihn in C# zu konvertieren.

Sie können JavaScript-Bibliotheken mithilfe der Blazor-JavaScript-Interoperabilität oder JS-Interop in Ihre Anwendungen integrieren. Sie verwenden JS-Interop zum Aufrufen von JavaScript-Funktionen aus .NET-Methoden und zum Aufrufen von .NET-Methoden über JavaScript-Funktionen. JS-Interop übernimmt das Marshalling von Daten und Objektverweisen zwischen Blazor und JavaScript für einen reibungslosen Übergang zwischen diesen.

Laden von JavaScript-Code in eine Blazor-App

Sie fügen JavaScript einer Blazor-App auf dieselbe Weise wie einer Standard-HTML-Web-App hinzu: mithilfe des HTML-Elements <script>. Sie fügen das <script>-Tag nach dem vorhandenen <script src="_framework/blazor.*.js"></script>-Tag je nach Blazor-Hostingmodell entweder in der Datei Pages/_Host.cshtml oder in der Datei wwwroot/index.html hinzu. Weitere Informationen finden Sie unter ASP.NET Core Blazor-Hostingmodelle.

Skripts sollten nicht in das <head>-Element der Seite eingefügt werden. Blazor steuert lediglich die Inhalte im <body>-Element einer HTML-Seite, sodass bei JS-Interop ein Fehler auftreten könnte, wenn die Skripts von Blazor abhängen. Außerdem ist die Seite möglicherweise langsamer, weil das Parsen des JavaScript-Codes Zeit in Anspruch nimmt.

Das <script>-Tag funktioniert wie in einer HTML-Web-App. Sie können Code direkt in den Text des Tags schreiben oder auf eine vorhandene JavaScript-Datei verweisen. Weitere Informationen finden Sie unter ASP.NET Core Blazor-JavaScript-Interoperabilität (JS-Interop): Speicherort von JavaScript.

Wichtig

Legen Sie JavaScript-Dateien im Ordner wwwroot Ihres Blazor-Projekts ab.

Eine andere Möglichkeit besteht darin, das <script>-Element, das auf eine JavaScript-Datei verweist, dynamisch in die Seite Pages/_Host.cshtml zu integrieren. Dieser Ansatz ist nützlich, wenn Sie in Abhängigkeit von Bedingungen, die nur zur Laufzeit bestimmt werden können, unterschiedliche Skripts laden müssen. Dieser Ansatz kann auch das erste Laden der App beschleunigen, wenn Sie die Logik mit einem Ereignis auslösen, das nach dem Rendern der Seite ausgelöst wird. Weitere Informationen finden Sie unter Starten von ASP.NET Core Blazor.

Aufrufen von JavaScript über .NET-Code

Sie verwenden die IJSRuntime zum Aufrufen einer JavaScript-Funktion aus .NET-Code. Um die JS-Interop-Runtime zur Verfügung zu stellen, fügen Sie eine Instanz der IJSRuntime-Abstraktion in eine Blazor-Seite am Anfang der Datei hinter der Anweisung @page ein.

Die IJSRuntime-Schnittstelle macht die Methoden InvokeAsync und InvokeVoidAsync zum Aufrufen von JavaScript-Code verfügbar. Verwenden Sie InvokeAsync<TValue>, um eine JavaScript-Funktion aufzurufen, die einen Wert zurückgibt. Rufen Sie andernfalls InvokeVoidAsync auf. Wie die Namen vermuten lassen, sind beide Methoden asynchron, also verwenden Sie den C#-Operator await, um Ergebnisse zu erfassen.

Der Parameter für die Methode InvokeAsync oder InvokeVoidAsync trägt den Namen der aufzurufenden JavaScript-Funktion, gefolgt von allen Argumenten, die die Funktion benötigt. Die JavaScript-Funktion muss Teil des window-Bereichs oder ein Unterbereich von window sein. Argumente müssen als JSON serialisierbar sein.

Hinweis

JS-Interop ist nur verfügbar, wenn die Blazor Server-App eine SignalR-Verbindung mit dem Browser hergestellt hat. Sie können Interop-Aufrufe erst tätigen, wenn das Rendering abgeschlossen ist. Um zu ermitteln, ob das Rendering abgeschlossen ist, verwenden Sie das OnAfterRender- oder OnAfterRenderAsync-Ereignis in Ihrem Blazor-Code.

Verwenden eines ElementReference-Objekts zum Aktualisieren des DOM

Blazor behält eine Darstellung des DOM als virtuelle Renderstruktur bei. Wenn sich die Seitenstruktur ändert, generiert Blazor eine neue Renderstruktur, die die Unterschiede enthält. Wenn die Änderungen abgeschlossen sind, durchläuft Blazor die Unterschiede, um die vom Browser angezeigte Benutzeroberfläche und die von JavaScript verwendete Browserversion des DOM zu aktualisieren.

Viele JavaScript-Bibliotheken von Drittanbietern stehen zum Rendern von Elementen auf einer Seite zur Verfügung, und diese Bibliotheken können das DOM aktualisieren. Wenn Ihr JavaScript-Code DOM-Elemente ändert, stimmt die Blazor-Kopie des DOM möglicherweise nicht mehr mit dem aktuellen Status überein. Dieser Umstand kann unerwartetes Verhalten und möglicherweise Sicherheitsrisiken hervorrufen. Es sollten keine Änderungen vorgenommen werden, die dazu führen könnten, die Blazor-Ansicht des DOM beschädigt wird.

Die einfachste Möglichkeit in dieser Situation ist das Erstellen eines Platzhalterelements in der Blazor-Komponente, meistens ein leeres <div @ref="placeHolder"></div>-Element. Der Blazor-Code interpretiert diesen Code als Leerraum, und die Blazor-Renderstruktur versucht nicht, den Inhalt nachzuverfolgen. Sie können <div> beliebig JavaScript-Codeelemente hinzufügen, und Blazor versucht nicht, diese zu ändern.

Der Blazor-App-Code definiert ein Feld vom Typ ElementReference, das den Verweis auf das Element <div> enthält. Das Attribut @ref für das Element <div> legt den Wert des Felds fest. Das ElementReference-Objekt wird dann an eine JavaScript-Funktion übergeben, die den Verweis verwenden kann, um dem <div>-Element Inhalt hinzuzufügen.

Aufrufen von .NET-Code aus JavaScript

JavaScript-Code kann eine .NET-Methode ausführen, die Ihr Blazor-Code definiert, indem er die Hilfsprogrammklasse DotNet verwendet, die Teil der JS-Interop-Bibliothek ist. Die DotNet-Klasse macht die Hilfsfunktionen invokeMethod and invokeMethodAsync verfügbar. Verwenden Sie invokeMethod, um eine Methode auszuführen und auf das Ergebnis zu warten, oder verwenden Sie invokeMethodAsync zum asynchronen Aufrufen der Methode. Die invokeMethodAsync-Methode gibt eine JavaScript-Promise zurück.

Tipp

Um die Reaktionsfähigkeit in Ihren Anwendungen zu erhalten, definieren Sie die .NET-Methode als async, und rufen Sie die Methode mithilfe von invokeMethodAsync über JavaScript auf.

Sie müssen die aufgerufene .NET-Methode mit JSInvokableAttribute taggen. Die Methode muss public sein. Zudem müssen alle Parameter als JSON serialisierbar sein. Der Rückgabetyp für eine asynchrone Methode muss zudem void, Task oder ein generisches Task<T>-Objekt sein, wobei T ein als JSON serialisierbarer Typ ist.

Um eine static-Methode aufzurufen, geben Sie den Namen der .NET-Assembly an, die die Klasse, einen Bezeichner für die Methode und alle Parameter enthält, die die Methode als Argumente für die Funktion invokeMethod oder invokeMethodAsync akzeptiert. Standardmäßig ist der Methodenbezeichner derselbe wie der Name der Methode, aber Sie können mithilfe des JSInvokable-Attributs einen anderen Wert angeben.

Aufrufen einer .NET-Instanzmethode aus JavaScript

Um eine Instanzmethode ausführen zu können, benötigt JavaScript einen Objektverweis auf die Instanz. JS-Interop bietet den generischen DotNetObjectReference-Typ, den Sie zum Erstellen eines Objektverweises im .NET-Code verwenden können. Der Code muss diesen Objektverweis für JavaScript verfügbar machen.

Der JavaScript-Code kann dann invokeMethodAsync mit dem Namen der .NET-Methode und allen Parametern aufrufen, die die Methode erfordert. Zur Vermeidung von Arbeitsspeicherverlusten sollte der .NET-Code den Objektverweis verwerfen, wenn dieser nicht mehr benötigt wird.

Wissen auf den Prüfstand stellen

1.

Wo sollten Sie das script-Tag hinzufügen, um auf eine JavaScript-Datei zu verweisen, die Sie in Blazor einschließen?

2.

Welche C#-Methode sollten Sie verwenden, um eine JavaScript-Funktion auszuführen, die void zurückgibt?