So verwenden Sie die jQuery-Benutzeroberfläche von der Blazor-Komponente

Lesezeit: 6 Minuten

Ich arbeite einige Blazor-Beispiele durch, und beim Versuch, mit einigen JSInterop-Lösungen zu arbeiten, bin ich auf ein Problem mit jQuery-UI-Elementen gestoßen. Ich bin kein erfahrener Javascript-Programmierer, aber ich bin mit .NET vertraut genug, sodass mir möglicherweise etwas Einfaches fehlt. Die erste Komponente der jQuery-Benutzeroberfläche, mit der ich zu arbeiten versucht habe, ist die Komponente “resizable”, die hier zu finden ist: https://jqueryui.com/resizable/

So sieht mein aktueller Code aus:

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <base href="https://stackoverflow.com/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        $( function() {
            $( "#resizable" ).resizable();
        });
    </script>
</body>
</html>

Ich bin mir sicher, dass das Problem nicht beim Laden der Bibliotheken liegt, und ich habe das Skript nach dem Laden platziert blazor.server.js.

Jetzt mein Index.cshtml hat folgendes im HTML-Teil:

<body>
    <div class="container-fluid">
        <div id="resizable" class="ui-widget-content">
            <div class="row row-no-gutters" style="width: 100%; height: 50%">
                <h3 class="ui-widget-header">Resizable</h3>
            </div>
        </div>
    </div>
</body>

Im Idealfall würde dies ein in der Größe veränderbares div ergeben, aber das resultierende HTML-Element ist nicht in der Größe veränderbar. Nach meinem Verständnis erfordert Blazor JSInterop keine Registrierung von JS-Funktionen mehr. Was mache ich falsch?

Das Problem ist das Timing: Ihre jQuery-Funktion wird ausgeführt, bevor Ihre Blazor-App gerendert wurde.

Ich habe das gelöst, indem ich das “onready” ($(...)) Funktion mit einer benannten Funktion (zB onBlazorReady), die ich dann von meinem Blazor aus aufrufe MainLayout Komponente zum richtigen Zeitpunkt.

Zur rechten Zeit OnAfterRender.

Zum Beispiel:

MainLayout.razor:

@code {
   [Inject]
   protected IJSRuntime JsRuntime { get; set; }

   protected override void OnAfterRender(bool firstRender)
   {
       if (firstRender)
           JsRuntime.InvokeVoidAsync("onBlazorReady");
   }
}

index.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width">
    <base href="https://stackoverflow.com/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        onBlazorReady() {
            $("#resizable").resizable();
        });
    </script>
</body>
</html>

Wie Sie sehen können, spritze ich IJSInterop damit ich meine anrufen kann onBlazorReady JS-Funktion, nachdem die LayoutComponent gerendert wurde.

  • Dieses Beispiel funktioniert nicht? blazorfiddle.com/s/kg13ms5x

    – 001

    25. November 2019 um 13:07 Uhr

  • Ich habe den Code bereitgestellt, um zu zeigen, wo was abgelegt werden soll – nicht als voll funktionsfähiges Beispiel – Sie würden ein vollständiges Projekt benötigen, damit die Dinge funktionieren.

    – Sipke Schoorstra

    26. November 2019 um 12:13 Uhr

  • @Isaac willst du das erklären?

    – Sipke Schoorstra

    26. November 2019 um 12:14 Uhr

  • Ich habe alle diese ausprobiert und keiner von ihnen scheint mit meinem Code zu funktionieren. Ich habe eine Blazor WASM PWA. In meiner Funktion habe ich die Zeile hinzugefügt: prompt(‘hey’); Es erschien zuvor, als die Seite noch ‘Loading…’ anzeigte. Ich weiß also, dass mein C#-Code die richtige Funktion aufruft, aber meine Animationen werden nicht angezeigt. Ich vermute, dass es immer noch ein Zeitproblem ist, aber ich kann kein anderes Lebenszyklusereignis finden, das ich verwenden könnte. Könnte es etwas mit WASM und/oder PWA sein, das die Animationen stören würde? Brad

    – Kodierer B

    11. Juni 2021 um 6:17 Uhr

Benutzer-Avatar
Sgedda

Funktioniert gut für mich, um Datepicker von jquery ui hinzuzufügen:

Razor-Komponentendatei.

@code {
    protected override async void OnAfterRender(bool firstRender)
    {
        await jsRuntime.InvokeVoidAsync("addDatePicker");
        base.OnAfterRender(firstRender);
    }
}

Globale Razor-Datei:

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Magiro.Blazor</title>
    <base href="https://stackoverflow.com/questions/54274629/~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
    <app>
        @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
    </app>

    <script src="_framework/blazor.server.js"></script>
    <script>
        window.addDatePicker = () => {
            $(".datepicker").datepicker();
        }
    </script>
</body>
</html>

Benutzer-Avatar
Löwe

Es besteht keine Notwendigkeit mehr, eine Methode auf der globalen Indexseite hinzuzufügen (_Hosts.cshtml in ASP.NET Core 5.0), wodurch diese Datei mit ansichtsspezifischer Logik und Abhängigkeiten gefüllt würde. Zumindest mit v5 haben wir IJSObjectReference damit wir anrufen können $('table').DataTable() direkt bei uns .razor Datei so:

<table>
    <thead>
        <tr>
            <td>Id</td>
            <td>Name</td>
        </tr>
    </thead>
    <tbody>
            <!-- your data -->
    </tbody>
</table>

@code {
    [Inject]
    protected IJSRuntime JSRuntime { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender) {
        if (firstRender) {
            var jQuery = await JSRuntime.InvokeAsync<IJSObjectReference>("$", "table");
            await jQuery.InvokeVoidAsync("DataTable");
        }
    }
}

Es ist auch möglich, Optionen mit einem anonymen Typ an das Plugin zu übergeben. Um beispielsweise die Suche zu deaktivieren, würden wir JS aufrufen

$('#example').dataTable({
  "searching": false
});

In Blazor erstellen wir einen anonymen Typ mit der gleichen Struktur und übergeben ihn als Parameter an die DataTable Forderung:

var options = new {
    searching = false
};
await jQuery.InvokeVoidAsync("DataTable", options);

Benutzer-Avatar
Flores

Die wahrscheinlichste Ursache ist das Timing. Die jQuery-Funktion wird ausgeführt, bevor die DOM-Elemente vorhanden sind.

Sie sollten den JS-Code als Interop-Funktion registrieren und diese danach aufrufen OnAfterRender Veranstaltung.

Benutzer-Avatar
asif juneja

Normalerweise benötigen Sie keine JQuery-Funktion wie readykönnen Sie einfach den gesamten erforderlichen Code in Ihre benutzerdefinierte js-Funktion einfügen, die auf ON_LOAD Ihrer Komponente ausgeführt werden sollte, wie von @Sipke Schoorstra in der obigen Antwort angegeben

1011480cookie-checkSo verwenden Sie die jQuery-Benutzeroberfläche von der Blazor-Komponente

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy