2021年2月5日金曜日

コンポーネントの表示制御について

コンポーネントの表示/非表示を制御する方法には、いくつか種類があります。それぞれ、簡単に紹介しようと思います。紹介する機能は、以下の4つです。

  • ビルド・オプション
  • 認可スキーム
  • サーバー側の条件
  • 動的アクションとクライアント側の条件

より正確には表示/非表示に限らず、コンポーネントの有効化/無効化を行います。目で見て分かりやすい有効化/無効化の効果が表示/非表示なので、それを例にとっています。表示されないプロセスやその他のコンポーネントにたいしても、同様に効果があります。


ビルド・オプション


ビルド・オプションについては以前に記事を書いています。ここでは簡単に設定について紹介します。

ビルド・オプションは共有コンポーネントアプリケーション・ロジックに含まれるビルド・オプションを開いて作成します。


今回は海外仕様というビルド・オプションを作成しています。


表示、非表示の制御はステータスによって決まります。コンポーネントのビルド・オプションとして、海外仕様が設定されている場合、このステータスが含めるであれば、リージョンは表示されます。逆に除外であれば、表示されません。


ほとんどのコンポーネントは、ビルド・オプションの設定を持っています。プロパティの構成に含まれるビルド・オプションにて、コンポーネントにビルド・オプションを設定します。


コンポーネントがリージョン、ページ・アイテムやボタンであれば、画面表示に関わるものなので表示/非表示が分かりやすい効果になります。プロセスなどのコンポーネントであれば、実行がされません。

ビルド・オプションにて除外されている場合は、そのコンポーネントがアプリケーション自体に存在しない、という扱いになります。


認可スキーム


認可スキームについても、以前に記事を書いています。こちらも簡単に設定の紹介をします。

認可スキームはは共有コンポーネントセキュリティに含まれる認可スキームを開いて作成します。


実体が分かりやすいリーダー権限を参照することで、認可スキームについて確認します。


リーダー権限は、スキーム・タイプブールを戻すPL/SQLファンクションになっています。他にも選択可能なスキーム・タイプはありますが、還元すると認可スキームは、真偽値を返すPL/SQLのファンクションです。


認可スキームで重要なのは、評価ポイントです。ビルド・オプションはステータスを含める、もしくは、除外にすると、その時点でアプリケーション全体の構成が変わります。認可スキームは、以下の4種類の評価ポイントがあり、その都度、評価されます。
  • セッションごとに1回
  • ページ・ビューごとに1回
  • コンポーネントごとに1回
  • 常時(キャッシュなし)
検証結果はキャッシュされるため(次に説明するサーバー側の条件に比べて)、パフォーマンス面で有利です。コンポーネントを有効にするか無効にするかを評価する際に、セッション・ステートに依存することが無ければ、認可スキームの利用を検討すべきです。

認可スキームの設定も、ほぼ全てのコンポーネントに含まれます。プロパティのセキュリティに含まれる認可スキームです。


認可スキームは、上記のコンポーネントへの設定以外にも、対話グリッドやフォームが行う操作の認可にも使われます。むしろ、こちらの使い方が本来の用途です。

サーバー側の条件


それぞれのコンポーネントを有効にするか無効にするか、そのコンポーネントが呼び出される際に評価する条件を設定できます。サーバー側の条件も還元すると真偽値を返すPL/SQLファンクションです。例えば、次のようなPL/SQLファンクション本体を設定すると、午前中だけリージョンが表示されます。

begin
if to_char(current_timestamp, 'AM') = '午前' then
return true;
end if;
return false;
end;


認可スキームとは異なり、コンポーネントが呼び出される度に評価されるため、その評価にセッション・ステートを使うことができます。セッション・ステートとは、APEXのセッションに紐づけられてデータベースに保存されている、アプリケーション・アイテムとページ・アイテムの値です。

セッション・ステートとして保持されている値は、開発者ツール・バーにあるセッションをクリックし、表示されるデバッグ画面より、ビューとしてセッション・ステートを選択し、設定をクリックすることで確認できます。


以下はデバッグ画面です。


ちなみに、Oracle APEXのアプリケーションは、セッションに紐づくデータをセッション・ステートとしてデータベースに保存(つまりディスクに保存)しているか、一時的な値であればブラウザ側で保持した状態になっていて、それ以外には一時的であってもデータは保持していません。そのため、データベースを再起動しても、Oracle APEXのセッションは継続します

サーバー側の条件は一番融通のきく設定なので、ビルド・オプションや認可スキームが適切であっても、ついついサーバー側の条件を使いがちです。サーバー側の条件を設定する前に、ビルド・オプションや認可スキームが向いていないか、検討してみましょう。

動的アクション


動的アクションによっても、コンポーネントの表示/非表示を制御できます。今までの設定は、評価でfalseが返ってくると、(表示に関連するコンポーネントであれば) HTML自体が生成されませんでした。

動的アクションの場合は、HTML自体は生成されていることが前提です。この違いはセキュリティの観点では重要です。ブラウザの開発者ツールを使って参照されると困るのであればサーバー側の設定などを使用し、動的アクションによる制御は使わないようにしましょう。

例えば、ページのロード時に、ブラウザがMac以外で動作している場合はリージョンを非表示にする動的アクションは以下のように定義します。

タイミングイベントページのロードとしています。クライアント側の条件として、タイプJavaScript式を選択し、以下の式を設定しています。

window.navigator.userAgent.indexOf("Macintosh") == -1


HTTPヘッダーのUser-AgentにMacintoshが含まれていなければ、Trueアクションとして登録されたアクションを実行します。上記では、非表示がTrueアクションです。

アクションとして非表示を選択し、選択タイプリージョン、非表示にするリージョンは動的アクション - Macなら表示を設定しています。


リージョンの表示・非表示に関していうと、非表示のアクションは対象となるHTML要素にstyle="display: none;"を追加しています。表示のアクションは、その設定を取り除いています。

最初の画面にあるボタンのクリックにより、ビルド・オプション、認可スキーム、サーバー側の条件、動的アクションそれぞれでリージョンの表示・非表示の動きを確認するアプリケーションのエクスポートを以下に置きました。(説明に使っている例はアプリケーションには含んでいません)。
https://github.com/ujnak/apexapps/blob/master/exports/component-controls.sql

Oracle APEXのアプリケーション開発の一助になれば幸いです。