Office ダイアログ API のベスト プラクティスとルール

この記事では、ダイアログの UI を設計し、シングルページ アプリケーション (SPA) で API を使用するためのベスト プラクティスなど、Office ダイアログ API のルール、概要、ベスト プラクティスについて説明します。

注:

この記事では、「Office アドインで Office ダイアログ API を使用する」で説明されているように、 Office ダイアログ API の使用の基本について理解していることを前提とします。

Office ダイアログ ボックスでのエラーとイベントの処理」も参照してください。

ルールと注意事項

  • ダイアログ ボックスは HTTP ではなく HTTPS URL にのみ移動できます。
  • displayDialogAsync メソッドに渡される URL は、アドイン自体とまったく同じドメインに存在する必要があります。 サブドメインにすることはできません。 ただし、渡されたページは、別のドメイン内のページにリダイレクトできます。
  • ホスト ページで一度に開くことができるダイアログ ボックスは 1 つだけです。 ホスト ページには、作業ウィンドウまたは関数コマンド関数ファイルを指定できます。
  • ダイアログ ボックスで呼び出すことができる Office API は 2 つだけです。
  • messageParent 関数は通常、アドイン自体とまったく同じドメイン内のページから呼び出す必要がありますが、これは必須ではありません。 詳細については、「ホスト ランタイムへのクロスドメイン メッセージング」をご覧ください。

ベスト プラクティス

ダイアログ ボックスを過度に使用しないようにする

UI 要素を重ねて表示することはお勧めできないため、シナリオで必要な場合を除き、作業ウィンドウでダイアログ ボックスを開かないようにします。 作業ウィンドウの表示領域の使用方法を検討するときには、作業ウィンドウはタブ表示できることに注意してください。 タブ付き作業ウィンドウの例については、 Excel アドイン JavaScript SalesTracker サンプルを参照してください。

ダイアログ ボックス UI をデザインする

ダイアログ ボックスのデザインのベスト プラクティスについては、「 Office アドインのダイアログ ボックス」を参照してください。

Office on the webでポップアップ ブロックを処理する

Office on the webの使用中にダイアログ ボックスを表示しようとすると、ブラウザーのポップアップ ブロックによってダイアログ ボックスがブロックされる可能性があります。 この場合、Office on the webは次のようなプロンプトを開きます。

ブラウザー内ポップアップ ブロックを回避するためにアドインが生成できる簡単な説明と [許可] ボタンと [無視] ボタンを含むプロンプト。

ユーザーが [許可] を選択すると、[Office] ダイアログ ボックスが開きます。 ユーザーが [無視] を選択すると、プロンプトが閉じられ、[Office] ダイアログ ボックスが開きません。 代わりに、 メソッドは displayDialogAsync エラー 12009 を返します。 コードでは、このエラーをキャッチし、ダイアログを必要としない代替エクスペリエンスを提供するか、アドインでダイアログを許可する必要があることをユーザーに通知するメッセージを表示する必要があります。 (12009 の詳細については、「 displayDialogAsync からのエラー」を参照してください)。

何らかの理由でこの機能をオフにする場合は、コードをオプトアウトする必要があります。メソッドに渡される DialogOptions オブジェクトを使用して、この要求を displayDialogAsync 行います。 具体的には、 オブジェクトに を含める promptBeforeOpen: false必要があります。 このオプションを false に設定すると、Office on the webはユーザーに対して、アドインによるダイアログの開きを許可するよう求めず、Office ダイアログは開かなくなります。

_host_info値を使用しない

Office は、_host_info に渡される URL に displayDialogAsync というクエリ パラメーターを自動的に追加します (カスタム クエリ パラメーターが存在する場合は、その後に追加されます。 カスタム クエリ パラメーター (存在する場合) の後に追加されます。 ダイアログ ボックスが移動する後続の URL には追加されません。 Microsoft は、この値の内容を変更したり、完全に削除したりする場合があるため、コードで読み取る必要はありません。 ダイアログ ボックスのセッション ストレージ (つまり、 Window.sessionStorage プロパティ) にも同じ値が追加されます。 この場合も、コードではこの値に対する読み取りも書き込みも行わないでください

閉じた直後に別のダイアログを開く

特定のホスト ページから複数のダイアログを開くことができないので、開いている ダイアログで Dialog.close を 呼び出してから別のダイアログ displayDialogAsync を開く必要があります。 メソッドは close 非同期です。 このため、 の呼び出しの直後に を呼び出 displayDialogAsync した場合、Office が 2 番目の closeダイアログを開こうとしたときに、最初のダイアログが完全に閉じていない可能性があります。 その場合、Office から 12007 エラーが返されます。"このアドインには既にアクティブなダイアログがあるため、操作は失敗しました" というエラーが返されます。

メソッドはcloseコールバック パラメーターを受け取りません。Promise オブジェクトは返されないため、キーワード (keyword)またはthenメソッドで待機awaitすることはできません。 このため、ダイアログを閉じた直後に新しいダイアログを開く必要がある場合は、次の手法をお勧めします。関数で新しいダイアログを開くコードをカプセル化し、 の displayDialogAsync 呼び出しで が返された場合に関数が再帰的に呼び出すように関数を設計します 12007。 次に例を示します。

function openFirstDialog() {
  Office.context.ui.displayDialogAsync("https://MyDomain/firstDialog.html", { width: 50, height: 50},
     (result) => {
      if(result.status === Office.AsyncResultStatus.Succeeded) {
        const dialog = result.value;
        dialog.close();
        openSecondDialog();
      }
      else {
         // Handle errors
      }
    }
  );
}
 
function openSecondDialog() {
  Office.context.ui.displayDialogAsync("https://MyDomain/secondDialog.html", { width: 50, height: 50},
    (result) => {
      if(result.status === Office.AsyncResultStatus.Failed) {
        if (result.error.code === 12007) {
          openSecondDialog(); // Recursive call
        }
        else {
         // Handle other errors
        }
      }
    }
  );
}

または、 setTimeout メソッドを使用して 2 番目のダイアログを開こうとする前に、コードを強制的に一時停止することもできます。 次に例を示します。

function openFirstDialog() {
  Office.context.ui.displayDialogAsync("https://MyDomain/firstDialog.html", { width: 50, height: 50},
     (result) => {
      if(result.status === Office.AsyncResultStatus.Succeeded) {
        const dialog = result.value;
        dialog.close();
        setTimeout(() => { 
          Office.context.ui.displayDialogAsync("https://MyDomain/secondDialog.html", { width: 50, height: 50},
             (result) => { /* callback body */ }
          );
        }, 1000);
      }
      else {
         // Handle errors
      }
    }
  );
}

SPA で Office ダイアログ API を使用するためのベスト プラクティス

通常、シングルページ アプリケーション (SPA) でクライアント側のルーティングが使用される場合は、別の HTML ページの URL ではなく、ルートの URL を displayDialogAsync メソッドに渡すことができます。 以下に示す理由から、これを行うことをお勧めします。

注:

この記事は、Express ベースの Web アプリケーションなど、 サーバー側 のルーティングには関係ありません。

SPA と Office ダイアログ API に関する問題

[Office] ダイアログ ボックスは、JavaScript エンジンの独自のインスタンスを持つ新しいウィンドウ内にあり、それ自体の完全な実行コンテキストです。 ルートを渡すと、基本ページとそのすべての初期化とブートストラップ コードがこの新しいコンテキストで再度実行され、すべての変数がダイアログ ボックスの初期値に設定されます。 そのため、この手法では、ボックス ウィンドウでアプリケーションの 2 番目のインスタンスをダウンロードして起動します。これは、SPA の目的を部分的に打ち破ります。 さらに、ダイアログ ボックス ウィンドウで変数を変更するコードでは、同じ変数の作業ウィンドウのバージョンは変更されません。 同様に、ダイアログ ボックス ウィンドウには独自のセッション ストレージ ( Window.sessionStorage プロパティ) があり、作業ウィンドウのコードからはアクセスできません。 ダイアログ ボックスと呼び出された displayDialogAsync ホスト ページは、サーバーに対して 2 つの異なるクライアントのように見えます。 (ホスト ページの内容のリマインダーについては、「ホスト ページ からダイアログ ボックスを開く」を参照してください)。

そのため、メソッドに displayDialogAsync ルートを渡した場合、実際には SPA はありません。 同じ SPA のインスタンスが 2 つあります。 さらに、作業ウィンドウ インスタンスのコードの多くは、そのインスタンスでは使用されません。ダイアログ ボックス インスタンス内のコードの多くは、そのインスタンスでは使用されません。 同じバンドルに 2 つの SPA があるようなものです。

Microsoft の推奨事項

クライアント側ルートを メソッドに displayDialogAsync 渡す代わりに、次のいずれかの操作を行うことをお勧めします。

  • ダイアログ ボックスで実行するコードが十分に複雑な場合は、2 つの異なる SPA を明示的に作成します。つまり、同じドメインの異なるフォルダーに 2 つの SPA を配置します。 1 つの SPA はダイアログ ボックスで実行され、もう 1 つはダイアログ ボックスのホスト ページで displayDialogAsync 実行されます。
  • ほとんどのシナリオでは、ダイアログ ボックスには単純なロジックのみが必要です。 このような場合、SPA のドメインに埋め込みまたは参照される JavaScript を含む 1 つの HTML ページをホストすることで、プロジェクトが大幅に簡略化されます。 ページの URL を displayDialogAsync メソッドに渡します。 これは、シングルページ アプリのリテラルアイデアから逸脱していることを意味します。Office ダイアログ API を使用している場合、SPA のインスタンスは実際には 1 つありません。