dynamisches Laden von JavaScript in Blazor 5

Ich hatte bereits die Probleme der Blazor Komponenten Hersteller beschrieben. Da statische Ressourcen per wwwroot Verzeichnis ausgeliefert  und per HTMl Referenz Link eingebunden werden müssen, kann man nicht einfach alles in eine DLL packen. Mit CSS Isolation ist das nun einfach gelöst.

Für vorbelastete Blazor Entwickler noch einmal der Hinweis. Bisher war es ein Window Objekt eine custom Function hinzugefügt.  Das wird neu als JS Module exportiert. Genannt wird das ganze JavaScript Object Isolation.

Im wwwroot wird also wie vorher eine JavaScript Datei für die Komponente angelegt. Bei mir per Verzeichnisname strukturiert. Die Funktion einfach mit export versehen.

   1:  export function HelloWorld(par) {
   2:      alert(`hello World ${ par }!`); 
   3:    
   4:  }

Jaja da waren sie wieder die JS Probleme. Die Zeichenkettenbegrenzer übrigens hier per BackTick (auf der deutschen Tastatur in der Regel rechts oben) und nicht single quote. Damit lässt sich das C# Feature String Interpolation mit $ nachbilden.

Die Blazor Komponente kann dann per JSRuntime Bridge die JavaScript Module Import Funktion aufzurufen. Also wir benötigen per DI die JSRuntime, ein Ivoke des import und ein Proxy vom Typ JSObjectReference.

   1:  @inject IJSRuntime JSRuntime
   2:  ..
   3:  <button @onclick="clickme">JS </button>

Im C# Code kann je nach Rendermode nur nach dem Rendering das Modul geladen werden, andernfalls gerne eine Fehlermeldung erscheint ala

InvalidOperationException: JavaScript interop calls cannot be issued at this time.This is because the component is being statically rendered.When prerendering is enabled, JavaScript interop calls can only be performed during the OnAfterRenderAsync lifecycle method.

 

   1:  @code {
   2:      IJSObjectReference js;
   3:      protected override async Task OnAfterRenderAsync(bool first)
   4:      {
   5:          js = await JSRuntime.InvokeAsync
<IJSObjectReference>("import", "/Components/Component.js");
   6:      }
   7:      void  clickme()
   8:      {
   9:          js.InvokeVoidAsync("HelloWorld","Hannes");
  10:      }
  11:  }

 

Wenn man das ganze in eine Razor Class Library Projekt packt, wird der Pfad zum JS Per Konvention _content/{LIBRARY NAME}/{PATH UNDER WWWROOT}.

Aus der Doku noch zur Ergänzung das Beispiel mit Rückgabewert

public async ValueTask<string> Prompt(string message)
{
    return await module.InvokeAsync<string>("showPrompt", message);
}
Kommentare sind geschlossen