Events Events Blazor like

Dieses Internet, erfunden um mich zu ärgern. Besonders diese Sprache, nur da um mein Leben zu versauen. Nicht nur das es eine Person erfunden hat, ganze Horden versammeln sich um ihre Ergüsse in Node Paketen zu bündeln. Da möchte man schon mal die Zeit zurück drehen.

image

Events sind in der HTML 5 Welt eigentlich ganz einfach. Ich würde sie am liebsten mit onclick registrieren, sehe aber auch ab und an die code lastigere Variante addEventListener("click" als adäquat an. Alles andere mit On und co ist mir schon zu viel.

Je nachdem welchens DOM Element und wer sich so ein Event schnappt, kann es auch durch die DOM Hierarchie bubbeln sehen. Die lieben Microsoft Blazor Entwickler haben das gemappt, so das man ganz easy User genrerierte Click Events in Blazor behandeln kann.

   1:  <div @onclick="clickdivout">
   2:  #test<div @onclick="clickdiv" @onplay="play" @onchange="change"  >
   3:  test2</div></div> 

In diesem Beispiel erhalten beide DIV das Click Event. Zustätzlich sind Events wie onplay oder onchange belegt, die ein DIV nicht erhalten kann. Blazor ist das vorerst mal egal, der C# Code kompiliert und lässt sich ausführen.

Im nächsten Schritt wird versucht, das click Event doppelt zu belegen. Das ist grundsätzlich mit addEventlistener in JavaScript möglich oder in C# +=.  Der von Microsoft vorgeschlagene Weg ist eine extra JavaScript Datei verlinkt in per _hosts.cshtml oder im Nofall direkt per <script> in gleicher Datei.

   1:  <script src="_framework/blazor.server.js"></script>
   2:  <script>
   3:      window.attachHandlers = () => {
   4:      document.getElementById("test").
addEventListener("click", function()
   5:      {
   6:           console.log("click handler called");
   7:      });

Das klappt aber nur, wenn man den Code Block nach dem Blazor render  der Componenet (.razor)ausführen lässt. Also muss man die JS Runtime Bridge bemühen  (Inject nicht vergessen) und die obige Methode Attachhandlers ausführen.

   1:  protected override void OnAfterRender(bool firstRender)
   2:   {
   3:    if(firstRender)
   4:     {
   5:      JSRuntime.InvokeVoidAsync("attachHandlers");
   6:     }
   7:  }

Wie vorhin schon geschrieben, ist man in Sachen Blazor Events auf Gedeih und Verderb den Redmonder Entwicklern ausgeliefert. Auch wenn Visual Studio dies per Intellisense bei @on vorschlägt bedeutet das noch lange nicht das ein Event auch in der C# Logik ausgelöst wird. Ein Play Event macht in einem DIV keinen Sinn, genauso wenig wie ein onload. Aber bei einem Image das größer ist, könnte man es brauchen.

   1:  <img src="bp.jpg"  @onload="load" width="100" heigth="80" >

 

Dazu braucht man eine Methode mit passender Signatur   void load(ProgressEventArgs e).

Jetzt würde man glauben, das wäre doch praktisch für Videos, weil die sind ja richtig groß. Aber weder onload noch onplay (bzw die JavaScript Events load/play) werden in Blazor ausgelöst.

   1:  <video id="myplayer" width="320" height="240" @onclick="clickdiv"
@onplay="play"
   2:  controls="true" @onload="loadv" @onchange="change">
   3:       <source src="/zug.mp4" type="video/mp4" >
   4:  </video>

Gar nichts davon. Die Microsoft Entwickler waren wohl kurz vorm Wochenende oder mögen keine Videos. Nur so eine Seitennotiz Webcam ist auch ein nogo in Blazorworld.

in der HTML Video Komponente sind keine Video typischen Events belegt. Dafür klappt onchange, was genau 0 Sinn ergibt, aber für einen Trick dienlich sein kann. Im folgenden wird ein Konzept beschrieben, wie man VIdeo Events (zb ended) in Blazor behandeln kann. Da dies ohnehin schon versauter Code ist, noch ergänzt um einen fiesen Trick (BL9992) um in Blazor .Razor Dateien direkt JavaScript einzubetten.

Wir fangen also per JS  das Play Event und machen es zu einem Change Event. Dabei könnte man den Namen des ursprünglichen Events als Value Parameter mitgeben, Hier einfach dummy genannt um die Idee zu beschreiben.

   1:  <script suppress-error="BL9992">
   2:      window.attachHandlers = () => {
   3:        var el=document.querySelector("video");
   4:        el.addEventListener('play', function () {
   5:               alert('play Clicked');
   6:               let event = new Event("change"); 
   7:               this['value']='dummy';
   8:               this.dispatchEvent(event);
   9:        });
  10:      }
  11:  </script>

Und in der Tat, Blazor onchange wird ausgelöst und der Parameter übergeben

   1:  void change(ChangeEventArgs args)
   2:  {
   3:     output="play change "+args.Value;
   4:  }

Dieser Artikel hat mich viele Stunden probieren gekostet. Das ist nicht dokumentiert und kann jederzeit von Microsoft geändert werden.

Kommentare sind geschlossen