JavaScript と Blazor との相互運用性

完了

Blazor は、JavaScript ではなく C# のコンポーネントを使用して、動的コンテンツを含む Web ページまたは HTML セクションを作成します。 ただし、Blazor と JavaScript の相互運用性 (JS 相互運用) を使用して、Blazor アプリで JavaScript ライブラリを呼び出したり、.NET C# コードから JavaScript 関数を呼び出したりすることができます。

このユニットでは、Blazor ページで C# コードから JavaScript を呼び出す方法と、JavaScript 関数から C# メソッドを呼び出す方法について学習します。 次のユニットでは、JavaScript ライブラリのアラート コンポーネントを使用して、Blazor のピザ配達 Web サイトを更新します。

Blazor と JavaScript の相互運用性を使用する

標準的な Blazor コンポーネントは、実行時に HTML をレンダリングするためのレイアウトとユーザー インターフェイスのロジックを使用します。 C# コードを使用すると、ユーザーや外部サービスと対話するイベントや、その他の動的なページ機能を処理できます。 多くの場合、JavaScript コードを利用する必要はありません。 代わりに、Blazor を .NET ライブラリと共に使用します。これにより、多くの同等の機能が提供されます。

ただし、既存の JavaScript ライブラリを使用しなければならない場合があります。 たとえば、JavaScript の一部のオープンソース ライブラリでは、コンポーネントのレンダリングやユーザー インターフェイス要素の処理を特殊な方法で行います。 もしくは、C# に変換する代わりに、再利用したい既存の試行およびテスト済みの JavaScript コードが存在する場合もあります。

Blazor と JavaScript の相互運用性 (つまり、"JS 相互運用") を使用して、JavaScript ライブラリをアプリケーションに統合できます。 JS 相互運用を使用して、.NET メソッドから JavaScript 関数を呼び出したり、JavaScript 関数から .NET メソッドを呼び出したりします。 JS 相互運用は、Blazor と JavaScript の間のデータおよびオブジェクト参照のマーシャリングを処理して、それらの間の切り替えを簡単にします。

Blazor アプリで JavaScript コードを読み込む

JavaScript は、HTML の <script> 要素を使用して、標準の HTML Web アプリに追加するのと同じ方法で Blazor アプリに追加します。 Blazor ホスティング モデルに応じて、Pages/_Host.cshtml ファイルまたは wwwroot/index.html ファイル内の既存の <script src="_framework/blazor.*.js"></script> タグの後に <script> タグを追加します。 詳細については、「ASP.NET Core Blazor のホスティング モデル」を参照してください。

ページの <head> 要素内にはスクリプトを配置しないことをお勧めします。 Blazor は HTML ページの <body> 要素内のコンテンツしか制御できないため、そのスクリプトが Blazor に依存していると、JS 相互運用が失敗する場合があります。 また、JavaScript コードの解析に時間がかかるため、ページが表示されるまでの時間が長くなる場合があります。

<script> タグは、HTML Web アプリの場合と同じように動作します。 タグの本体内に直接コードを記述することも、既存の JavaScript ファイルを参照することもできます。 詳細については、「ASP.NET Core Blazor JavaScript の相互運用性 (JS 相互運用): JavaScript の場所」を参照してください。

重要

JavaScript ファイルは、Blazor プロジェクトの wwwroot フォルダーの下に配置してください。

別のオプションとして、JavaScript ファイルを参照する <script> 要素を Pages/_Host.cshtml ページに動的に挿入する方法があります。 このアプローチは、実行時にのみ決定できる条件に応じて、異なるスクリプトを読み込む必要がある場合に役立ちます。 また、このアプローチでは、ページがレンダリングされた後に発生するイベントでロジックをトリガーする場合に、アプリの最初の読み込みを高速化することもできます。 詳細については、「ASP.NET Core Blazor の起動」を参照してください。

.NET コードから JavaScript を呼び出す

.NET コードから JavaScript 関数を呼び出すには、IJSRuntime を使用します。 JS 相互運用ランタイムを使用可能にするには、IJSRuntime 抽象化のインスタンスを、Blazor ページのファイルの先頭付近にある @page ディレクティブの後に挿入します。

IJSRuntime インターフェイスは、InvokeAsyncInvokeVoidAsync のメソッドを公開して JavaScript コードを呼び出します。 値を返す JavaScript 関数を呼び出すには InvokeAsync<TValue> を使用します。 それ以外の場合は、InvokeVoidAsync を呼び出します。 名前が示すとおり、どちらのメソッドも非同期であるため、C# await 演算子を使用して結果をキャプチャします。

InvokeAsync または InvokeVoidAsync メソッドのパラメーターは呼び出す JavaScript 関数の名前で、その後に関数に必要な引数が続きます。 JavaScript 関数は、window スコープの一部か、または window のサブスコープである必要があります。 引数は JSON シリアル化可能である必要があります。

Note

JS 相互運用は、Blazor Server アプリでブラウザーとの SignalR 接続が確立されている場合にのみ使用できます。 レンダリングが完了するまで、相互運用機能の呼び出しを行うことはできません。 レンダリングが完了したかどうかを検出するには、Blazor コード内で OnAfterRender または OnAfterRenderAsync イベントを使用します。

ElementReference オブジェクトを使用して DOM を更新する

Blazor では、ドキュメント オブジェクト モデル (DOM) の表現を "仮想レンダリング ツリー" として保持します。 ページ構造が変更されると、Blazor では、それらの違いが含まれた新しいレンダリング ツリーを生成します。 変更が完了すると、Blazor ではこれらの違いを反復処理して、ユーザー インターフェイスのブラウザー表示と、JavaScript で使用される DOM のブラウザー バージョンを更新します。

多くのサードパーティーの JavaScript ライブラリは、ページ上の要素をレンダリングするために使用でき、これらのライブラリは DOM を更新できます。 JavaScript コードで DOM の要素を変更した場合は、DOM の Blazor のコピーが現在の状態と一致しなくなる可能性があります。 この状況により予期しない動作が発生し、セキュリティ リスクが発生する場合があります。 DOM の Blazor ビューが壊れるような変更は行わないことが重要です。

この状況を処理するための最も簡単な方法は、Blazor コンポーネントでプレースホルダー要素を作成することです。通常は空の <div @ref="placeHolder"></div> 要素です。 Blazor コードでは、このコンテンツを空白領域と見なし、Blazor レンダリング ツリーでそのコンテンツを追跡しようとしません。 この <div> に自由に JavaScript コード要素を追加することができ、Blazor ではそれを変更しようとしません。

Blazor アプリ コードは、<div> 要素への参照を保持する型 ElementReference のフィールドを定義します。 <div> 要素の @ref 属性は、フィールドの値を設定します。 その後、ElementReference オブジェクトは JavaScript 関数に渡されます。この関数は、参照を使用して <div> 要素にコンテンツを追加できます。

JavaScript から .NET コードを呼び出す

JavaScript コードは、JS 相互運用ライブラリの一部である DotNet ユーティリティ クラスを使用して、Blazor コードが定義する .NET メソッドを実行できます。 DotNet クラスは、ヘルパー関数 invokeMethodinvokeMethodAsync を公開します。 invokeMethod を使用してメソッドを実行し、結果を待つか、invokeMethodAsync を使用してメソッドを非同期的に呼び出します。 invokeMethodAsync メソッドからは、JavaScript Promise が返されます。

ヒント

アプリケーションの応答性を維持するには、.NET メソッドを async として定義し、それを JavaScript から invokeMethodAsync を使用して呼び出してください。

JSInvokableAttribute で呼び出される .NET メソッドにはタグを付ける必要があります。 このメソッドは public である必要があり、パラメーターはすべて JSON シリアル化可能である必要があります。 さらに、非同期メソッドの場合は、戻り値の型が voidTask、または汎用の Task<T> オブジェクトである必要があります。ここで、T は JSON シリアル化可能な型です。

static メソッドを呼び出すには、そのクラスを含む .NET アセンブリの名前、そのメソッドの識別子、そのメソッドが invokeMethod または invokeMethodAsync 関数への引数として受け付けるすべてのパラメーターを指定します。 既定では、メソッド識別子はそのメソッドの名前と同じですが、JSInvokable 属性を使用して別の値を指定することができます。

JavaScript から .NET インスタンス メソッドを呼び出す

インスタンス メソッドを実行するには、JavaScript に、そのインスタンスを指すオブジェクト参照が必要です。 JS 相互運用には、.NET コード内にオブジェクト参照を作成するために使用できる汎用の DotNetObjectReference 型が用意されています。 このコードは、このオブジェクト参照を JavaScript から使用できるようにする必要があります。

その JavaScript コードでは次に、.NET メソッドの名前と、そのメソッドに必要なすべてのパラメーターを使用して invokeMethodAsync を呼び出すことができます。 メモリ リークを回避するために、.NET コードでは、必要がなくなったオブジェクト参照を破棄する必要があります。

自分の知識をチェックする

1.

Blazor に含める JavaScript ファイルを参照するには、script タグをどこに追加する必要がありますか?

2.

void を返す JavaScript 関数を実行するために使用する C# メソッドは次のうちのどれですか?