Blazor (technologia do tworzenia interaktywnych aplikacji webowych w .NET) oferuje mechanizm JavaScript Interop, który pozwala wywoływać funkcje JavaScript z poziomu kodu C# i odwrotnie – wywoływać metody .NET z kodu JavaScript. To przydatne w sytuacjach, gdy chcemy skorzystać z istniejącej biblioteki JS lub przeglądarkowego API w naszej aplikacji Blazor WebAssembly. W tym artykule pokażę w prosty sposób, jak wykonać takie wywołania w obu kierunkach.
Wywołanie funkcji JavaScript z kodu .NET w Blazor
Blazor (zarówno WebAssembly, jak i Server) umożliwia wywoływanie kodu JavaScript poprzez wstrzyknięcie specjalnej usługi IJSRuntime do komponentu. Następnie możemy użyć jej metody InvokeAsync lub InvokeVoidAsync do wykonania funkcji JS.
Załóżmy, że chcemy wywołać prostą funkcję JavaScript – na przykład wyświetlić okienko alert z komunikatem. Możemy to zrobić tak:
@inject IJSRuntime JS
<button @onclick="ShowAlert">Wyświetl alert</button>
@code {
private async Task ShowAlert()
{
await JS.InvokeVoidAsync("alert", "To jest komunikat z .NET!");
}
}W powyższym kodzie najpierw wstrzykujemy (@inject) usługę IJSRuntime do komponentu Blazor. Następnie, po kliknięciu przycisku, metoda C# ShowAlert wywołuje JS.InvokeVoidAsync("alert", "..."). Pierwszy argument to nazwa funkcji JavaScript, której chcemy użyć – w tym wypadku wbudowana alert (osiągalna w window.alert). Kolejne argumenty (tutaj jeden string) to parametry przekazywane do funkcji JS. Metoda InvokeVoidAsync służy do wywoływania funkcji, które nic nie zwracają (void), a gdybyśmy chcieli odebrać wynik z JS, używamy InvokeAsync<T> z odpowiednim typem T.
Wskazówka: Możemy wywołać dowolną funkcję dostępną w kontekście przeglądarki. Jeśli definiujemy własne skrypty, upewnijmy się, że są załadowane (np. umieszczone w wwwroot/index.html w przypadku Blazor WebAssembly) i dostępne globalnie lub jako moduł. W nowoczesnym Blazorze można też importować moduły JS (IJSRuntime.InvokeAsync<IJSObjectReference>("import", "script.js")), jednak dla prostoty początkujący mogą na starcie trzymać się wywołań funkcji globalnych.
Po uruchomieniu powyższego przykładu kliknięcie przycisku spowoduje wyświetlenie alertu z tekstem przekazanym z C#. W ten sposób z Blazora możemy korzystać z funkcji JavaScript – od prostych console.log czy alert, aż po wywołania zewnętrznych bibliotek (np. map, wykresów) i API przeglądarki, których Blazor sam w sobie nie obsługuje.
Wywołanie funkcji .NET z kodu JavaScript (JavaScript wywołuje C#)
Interoperacyjność działa też w drugą stronę – JavaScript może wywołać metody C# w aplikacji Blazor. Najczęściej wykorzystuje się to rzadziej niż wywołania JS z .NET, ale bywa niezastąpione np. przy obsłudze zdarzeń przeglądarki lub integracji z bibliotekami, które oczekują wywołań zwrotnych (callbacks).
Aby JavaScript mógł wywołać metodę C#, ta metoda musi być udostępniona za pomocą atrybutu [JSInvokable]. Najprościej udostępnić metodę statyczną. Przykładowo, dodajmy w naszym komponencie Blazor (lub innym klasie C#) metodę zwracającą powitanie:
@code {
[JSInvokable]
public static string WelcomeMessage(string name)
{
return $"Witaj, {name}!";
}
}Dzięki [JSInvokable] powyższa metoda może zostać wywołana z JavaScript. Jak to zrobić po stronie JS? Należy skorzystać z obiektu DotNet, który Blazor udostępnia w kontekście przeglądarki. Użyjemy metody DotNet.invokeMethodAsync, przekazując nazwę assembly (projektu) naszej aplikacji Blazor oraz nazwę metody C#:
<script>
// Wywołanie metody .NET z JavaScript
DotNet.invokeMethodAsync('MyBlazorApp', 'WelcomeMessage', 'Blazor')
.then(result => {
alert(result); // powinno wyświetlić: "Witaj, Blazor!"
});
</script>W powyższym skrypcie MyBlazorApp to nazwa naszej aplikacji/assembly .NET (należy ją zamienić na rzeczywistą nazwę projektu). Metoda invokeMethodAsync wywołuje wskazaną metodę .NET i zwraca Promise, stąd możemy dołączyć .then(...) aby obsłużyć wynik asynchronicznie (np. wyświetlić go). W naszym przypadku metoda C# zwraca string powitalny, który JS otrzymuje i pokazuje w alertcie.
Jeśli chcemy wywołać niestatyczną metodę instancji (np. metodę w konkretnym komponencie lub obiekcie), jest to również możliwe z użyciem DotNetObjectReference – wtedy przekazujemy odwołanie do instancji obiektu do JavaScript i wywołujemy na nim metodę. Jednak dla początkujących łatwiej jest zacząć od podejścia ze statycznymi metodami i JSInvokable.
Podsumowanie
Blazor umożliwia płynną integrację z JavaScript, co otwiera drogę do wykorzystania ogromnego ekosystemu bibliotek JS oraz przeglądarkowych API w aplikacjach .NET. Pokazałem Ci, jak wywołać funkcje JavaScript z C# (np. do wyświetlenia powiadomienia czy użycia konsoli) oraz jak z poziomu JavaScript wywołać metody napisane w .NET. Taka dwukierunkowa komunikacja bywa niezbędna w zaawansowanych scenariuszach — warto jednak używać jej świadomie, tam gdzie rzeczywiście potrzebujemy sięgnąć poza możliwości czystego Blazora.
Przy okazji jeśli chcesz lepiej poznać Blazora od podstaw, krok po kroku, rozważ dołączenie do mojego kompletnego szkolenia online: Szkoła Blazora. Znajdziesz tam uporządkowaną wiedzę, praktyczne przykłady i więcej technik (w tym JavaScript interop) omówionych bardziej szczegółowo. Powodzenia w eksperymentach z Blazorem i JavaScript – mam nadzieję, że dwukierunkowe wywołania funkcji nie będą już dla Ciebie zagadką.