ユーザー エクスペリエンスの拡張性

完了

ローコードのアプローチで、ユーザー エクスペリエンスの要件を満たすことが難しかったり、不可能だったりする場合は、コードを作成して開発するのが一般的です。 開発者がユーザー エクスペリエンスを強化するために最もよく使用する 2 つのアプローチがあります。それは、Power Apps Component Framework のコード コンポーネントを作成する方法と、クライアント スクリプトを実装する方法です。 コード コンポーネントでは、キャンバス アプリやモデル駆動型アプリで既成のコントロールと同じように使用できる、カスタム ビジュアルを実装することができます。 クライアント スクリプトは視覚化を目的とするのではなく、プログラムによる方法でビジネス ルールを実装することを目的としています。 クライアント スクリプトは、モデル駆動型アプリにのみ適用されます。 どちらの手法も規範的なパターンとオブジェクト モデルに従っており、拡張性のためにどちらかを使用する場合には注意が必要です。 このトピックの残りの部分では、これらのオプションについて詳しく説明します。

Power Apps Component Framework

コード コンポーネントは、HTML、CSS、および TypeScript を使用して実装されます。 特定の UI フレームワークを使用する必要はないのですが、React がよく使用されます。

コード コンポーネントを作成するには、一貫した方法でアプリをホスティングし、コンポーネントと対話するためにインターフェイスを実装する必要があります。 インターフェイスを実装するコード コンポーネントを開発するには、最初に Power Platform コマンドライン インターフェイス (CLI) ツールを使用して、列またはデータセットのテンプレートにあるコンポーネント ファイルを初期化します。 このテンプレートには、インターフェイスの実装に必要なプレースホルダーが含まれています。

CLI ツールは、コンポーネントをリソースとして作成するために必要なファイルが記述されたマニフェスト ファイルを作成します。 また、そのコンポーネントをホストしているアプリケーションで使用できるプロパティも記述されます。 次の例では、companyName プロパティが定義されています。

このコンポーネントをアプリ開発者が使用する場合、会社名の値を静的に設定するか、アプリケーションで使用可能なデータ列のいずれかに動的にバインドするかを選択できます。 プロパティを使用すると、アプリケーションとコンポーネントがデータをやり取りする際に、コンポーネントの実装についてアプリの側で理解する必要が無くなります。

マニフェストでは、機能を有効にすることもできます。 マニフェストに必要な記述を追加することで機能を有効にすると、その機能に関連付けられたネイティブ API を使用して、コンポーネントのロジックをコーディングできます。 たとえば、Device.captureAudio 機能を有効にすると、デバイスのマイクを起動してオーディオを録音するための制御を行うコードを作成できます。

<feature-usage> <uses-feature name="Device.captureAudio" required="true" /> <uses-feature name="Device.captureImage" required="true" /> <uses-feature name="Device.captureVideo" required="true" /> <uses-feature name="Device.getBarcodeValue" required="true" /> <uses-feature name="Device.getCurrentPosition" required="true" /> <uses-feature name="Device.pickFile" required="true" /> <uses-feature name="Utility" required="true" /> <uses-feature name="WebAPI" required="true" /> </feature-usage>

アプリ ランタイムは、ライフサイクルや、ホスト型コード コンポーネントとの通信を管理します。 これは、コード コンポーネントのクラスに StandardControl インターフェイスを実装することで可能になります。

export class FirstControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {}

このインターフェイスでは、次のメソッドを実装する必要があります。

  • init - コンポーネントのインスタンスを初期化するために使用します。 コンポーネントはリモート サーバーの呼び出しや、その他の初期化アクションを開始できます。

  • updateView - プロパティ バッグ内の値が変更されたときに呼び出されます。 これには、列の値、データセット、コンテナーの高さや幅などのグローバル値、オフライン状態、ラベルや表示などのコンポーネント メタデータ値、その他が含まれます。

  • destroy - コンポーネントが DOM ツリーから削除されるときに呼び出されます。 クリーンアップや、コンポーネントが使用しているメモリを解放するために使用されます。

  • getOutputs (オプション) - コンポーネントが新しいデータを受け取る前に、フレームワークによって呼び出されます。 マニフェストに定義された分類に基づいてオブジェクトを返します。バインドとしてマークされたプロパティのオブジェクトを必要とします。

コード コンポーネントでは、必要最低限の要素を実装するだけで、ホスティング アプリとの通信や操作を一貫した方法で行うことができます。

クライアント スクリプト

クライアント スクリプトを使用すると、Power Apps のモデル駆動型アプリで JavaScript を使用してビジネス ルールを実装できます。 クライアント スクリプトは、宣言型のビジネス ルールが要件を満たさない場合に、代わりに使用されます。 クライアント スクリプトは、次のフォームイベントに応答して、モデル駆動型フォームで実行されます。

  • フォームの読み込み

  • 列のデータの変更

  • フォームの保存

また、コマンド バー ボタンを押すと、クライアント スクリプトが起動するように構成することもできます。

JavaScript でロジックを記述する場合は、フォームが単なる HTML であっても、フォームの内容を直接操作することはできないことに注意する必要があります。 クライアント スクリプトのオブジェクト モデルでは、メソッド呼び出しを使用してさまざまなフォーム コンポーネントを操作することができます。 そのため、フォームのレンダリングに使用するレイアウトや HTML を変更しても、ビジネス ロジックがその影響を受けることはありません。

以下は、フォームの読み込みと列の変更を処理するクライアント スクリプトの例です。

// A namespace defined for the sample code
// As a best practice, you should always define 
// a unique namespace for your libraries
var Sdk = window.Sdk || {};
(function () {
    // Define some global variables
    var myUniqueId = "_myUniqueId"; // Define an ID for the notification
    var currentUserName = Xrm.Utility.getGlobalContext().userSettings.userName; // get current user name
    var message = currentUserName + ": Your JavaScript code in action!";

    // Code to run in the form OnLoad event
    this.formOnLoad = function (executionContext) {
        var formContext = executionContext.getFormContext();

        // display the form level notification as an INFO
        formContext.ui.setFormNotification(message, "INFO", myUniqueId);

        // Wait for 5 seconds before clearing the notification
        window.setTimeout(function () { formContext.ui.clearFormNotification(myUniqueId); }, 5000);
    }

    // Code to run in the attribute OnChange event 
    this.attributeOnChange = function (executionContext) {
        var formContext = executionContext.getFormContext();

        // Automatically set some column values if the account name contains "Contoso"
        var accountName = formContext.getAttribute("name").getValue();
        if (accountName.toLowerCase().search("contoso") != -1) {
            formContext.getAttribute("websiteurl").setValue("https://www.contoso.com");
            formContext.getAttribute("telephone1").setValue("425-555-0100");
            formContext.getAttribute("description").setValue("Website URL, Phone and Description set using custom script.");
        }
    }

    // Code to run in the form OnSave event 
    this.formOnSave = function () {
        // Display an alert dialog
        Xrm.Navigation.openAlertDialog({ text: "Record saved." });
    }
}).call(Sdk);

こちらの 完全なチュートリアル では、この例をフォームに適用する方法について詳しくご覧いただけます。

クライアント スクリプトを使用して開発すると、列の適切な非表示/表示、データの検証、またはその他の一般的なタスクにおいて、ユーザーがよりアプローチしやすいフォームを作成し、ユーザー エクスペリエンスを改善することができます。