次の方法で共有


コントロールのチェックリスト

この記事では、コントロールのすべてのリリース条件を分類して説明しています。

はじめに

通常、新しいコントロールを作成する場合、主にシナリオ機能と技術的な実装に焦点を当てます。 ただし、この記事で説明されているように、コントロールが出荷できる状態になったと見なされる前に、一連のベスト プラクティス、品質、および開発リリース基準に準拠している必要があります。

コントロール基準のチェックリスト

このチェックリストは、コントロール開発の基本について熟知していることを前提としています。 次の項目では、すべてのコントロールで満たす必要がある重要な実装要件を強調表示しています。

基本的な使用準備

コントロールは、機能的に互換性がある完全なコントロールとみなされるために、これらの要件を満たす必要があります。

クラス

これらの命名規則はベスト プラクティスですが、コントロールの機能要件ではありません。

  • ランタイム クラスの名前は、[コントロール名]Control です。
  • デザイン時クラスの名前は、Build[コントロール名]Control です。
  • すべてのコントロール固有のコンポーネント クラスの名前は、[コントロール名][コンポーネント名]Component です。
  • すべての一般的なコンポーネント クラスの名前は、Build[コンポーネント名]Component です。

リソース

これらの命名規則はベスト プラクティスですが、コントロールの機能要件ではありません。

  • HTML リソースの名前は、[コントロール名]HTM で、物理ファイルの名前は[コントロール名].htm です。
  • JavaScript リソースの名前は、[コントロール名]JS で、物理ファイルの名前は[コントロール名].js です。

X++ ランタイム

これらの項目は、"Runtime" X++ クラスに適用されます。

  • FormControlAttribute はビルド クラス名で指定されています。
  • FormControlAttribute は、テンプレート ID で指定されています。
  • FormControlAttribute はリソース バンドル パスで指定されています。
  • FormTemplateControl クラスは拡張されます (直接または継承を通じて)。
  • FormProperty は、change-tracked プロパティ (つまり、クライアント JavaScript で読み取る必要のある各プロパティ) に対して存在します。
  • 新規 メソッドは、各 FormProperty インスタンスを初期化します。
  • setTemplateId および setResourceBundleName 継承メソッドは、FormControlAttribute で指定された同じ値を使用して呼び出されます。
  • ApplyBuild メソッドは、デザイン時プロパティを解釈するため、コントロールに応じて実行時のプロパティにデザイン時のプロパティを適用するために使用されます。
  • 各 FormProperty に対して、プロパティ ゲッター / セッター メソッドが存在します。
  • FormPropertyAttribute は、各 FormProperty のゲッター / セッター メソッドで提供されます。
  • Anytype は、FormPropertyKind::BindableValue を持つ FormProperties の引数タイプとして使用されます。
  • すべての FormProperties は FormPropertyAttribute の第 3 引数を経由して JS クラスに ReadOnly として指定されます。
    • この引数は、X++ ではなく、JavaScript によって認識される読み取り/書き込み動作にのみ影響します。
    • すべてプロパティ状態の変更を検証する必要があるため、プロパティに JavaScript で直接書き込むを許可することはお勧めしません。 この目的に、書き込み可能なプロパティではなく、FormCommands を使用することをお勧めします。
  • FormProperties の状態が変更されるようにする FormCommands は、コントロールが有効な状態でプロパティの変更を許可するように、検証する必要があります。
    • 無効、読み取り専用、非表示などのコントロールは、不適切な状態変更を防止する必要があります。

X++ デザイン時間

これらの項目は、"Design/Build" X++ クラスに適用されます。

  • FormDesignControlAttribute は、コントロール共有名である [コンポーネント名] として、末尾に “Control” の追加無しで指定されます。
    • コントロールがフォームに追加されると、ここで指定された名前が Microsoft Visual Studio に表示されます。
  • 各デザイン時のプロパティに対して、バッキング フィールドが存在します。
  • 各デザイン時のプロパティに対して、プロパティ ゲッター / セッターが存在します。
  • FormDesignPropertyAttribute は、各デザイン時のプロパティに提供されます。
  • このクラスに必要なデザイン プロパティのゲッター/セッターの外部にあるコードはありません。 (つまり、new() 方法などは存在しません。)

HTML

これらの項目は、リソース バンドルとも呼ばれる .htm ファイルに適用されます。

  • スクリプト、スタイルシート、その他の HTM ファイルなどの外部リソースは、HTML 標準 <script> および <link> タグをしようしてロードされます。
  • すべての外部リソースの読み込みタグはファイル内の最も外側の HTML 要素上に配置、および読み込みがされ、最初に処理されます。
  • テンプレート ID は、最も外側の HTML 要素の id 属性を介して供給されます。
  • 一番外側の HTML 要素の可視性は Visible プロパティにバインドされています。
  • 最も外側の HTML 要素のサイズ変更はサイズ変更バインド ハンドラーにバインドされます。
  • バインディング ハンドラーはプログラムで HTML を変更するために使用されます。 (JavaScript コンストラクターの getElementById などの API は使用されません。)

JavaScript

  • JavaScript コード全体が無名関数にラップされています。
  • ローカライズ可能な文字列は、カルチャ情報のグローバル化オブジェクトに格納されます。
  • ローカライズ可能な文字列は、 ローカライズ可能なラベルの作成 に記載の指示に従ってラベル ファイルに格納されます。
  • コンストラクター内で初期化されていないすべてのプロパティに対して、既定値が提供されます。
  • JavaScript コンストラクターは、コントロール JavaScript 名前空間に追加されます。
  • これへの参照は、本人という名前のオブジェクトに格納され、コンストラクター全体でこれの代わりに本人が使用されます。
  • 基本の JavaScript コントロール動作が継承されます。
  • 既定値は、フレームワーク ユーティリティ関数を使用して適用されます。
  • クライアント側のプロパティはコントラクターのスコープ内で定義され、自己に追加されます。
  • 監視可能な計算されたプロパティは、UI バインド動作に対してのみ使用されます。
  • プロトタイプが存在し、コントロールに固有の静的メソッドがすべて含まれています。
  • コントロールに固有のバインディング ハンドラーはコントロールの名前空間 (グローバル コントロールの名前空間ではない) に格納されます。
  • コントロールは外部プラグイン (Microsoft ActiveX、Flash、Java など) を使用したり読み込んだりしません。

インタラクティビティ

CSS/LESS

  • すべてのクラス名の接頭語として、他のコントロールと競合を避けるためのテンプレート ID を付けます。
  • これらのクラスは変更可能なため、他のコントロールで定義されているクラス名は使用しないでください。

レイアウトとサイズ変更

  • コントロールは、最も外側の要素にサイジング API を使用します。 この要件により、フレームワークがコントロールの最も外側の要素のサイズと配置を正しく行うことが保証されます。
  • コントロールに含まれる要素に対する高度なレイアウト シナリオでは、HTML 標準でサポートされている CSS 変動ボックス を使用します。

ブラウザー サポート

  • コントロールは、サポートされているすべてのブラウザーで、意図したすべてのユーザー操作パターンを正しくレンダリングおよびサポートします:
    • Microsoft Edge/Internet Explorer 11
    • 最新バージョンの Chrome
    • iPad/MacOS Safari の最新バージョン

タブ順序

  • コントロールがタブ順の W3C 基準を満たしていることを確認します。

グローバリゼーション

右から左 (言語)

  • 完全な RTL サポートは、RTW 後に到着します。

ローカライズ可能なラベル

  • コントロールは、クライアント側でのみ使用される UI テキスト用のラベル ファイルを使用します (X++ では使用されません)。 これらのラベルを作成および使用する方法については、 ローカライズ可能なラベルを作成する を参照してください。

タスク レコーダーの互換性

  • 基本的な記録サポート
    • ユーザー入力を受け入れる、またはユーザーが対話できる任意のコントロールに関しては、入力/アクションはタスク レコーダーで記録可能である必要があります。 入力を記録するタスク レコーダーは、コントロールは、記録されるべきプロパティを指定するのに SysTaskRecorder X++ API を使用する必要があります。
  • 基本的なタスク ガイド サポート
    • タスク レコーダーを使用して記録される任意のコントロールについては、そのコントロールにはタスク ガイド サポートがある必要があります。 このサポートには、記録された入力/アクションを基に、タスク ガイド ポップアップ プロンプトがコントロールの正しい UI 要素を指しているかを確認することが含まれます。
    • さらに、タスク ガイドがロックされている (「オンレール」) 場合に、ユーザーがコントロールの期待された部分と対話できることを検証します。 たとえば、コンボ ボックス コントロールに対して、ユーザーは値を直接入力することに加えて、値を選択するドロップダウン ボックスを開ける必要があります。
  • 高度な記録サポート
    • 切り取り、コピー、貼り付け、および検証のサポートは、コントロールごとに評価することができます。 これらの機能を有効にするためのコントロールが実装できる JavaScript と X++ の各メソッドがあります。

コントロールの脅威モデリング

  • データ型のシリアル化/逆シリアル化とコマンド/プロパティの実行に関連する論理コントロール (X + +/C++) の脆弱性を、確認および修復する必要があります。
    • シリアル化脅威は、コントロールがデータ型を解析または解釈する方法に関連付けられます。
      • データ型のシリアライザ (組み込み X++ データ コントラクトおよびプリミティブ型のシリアル化を除く) を確認する必要があります。
      • 任意のパーサーは、任意のコードの実行またはその他の悪用を許可していないことを確認するためにレビューする必要があります。
      • コントロール (またはコントロールを使用するすべてのヘルパー クラス) により実行されるすべてのデータ アクセスのクエリは評価および確認される必要があります。
    • コマンド/プロパティの実行の脅威は、コントロールが無効と判断したアクションを論理コントロールが処理する方法に関連しています。
      • コマンド問題の例: クリック コマンドは、コントロールが無効状態のときに実行されます。 コントロール ステートに基づいて、クリック コマンドが適切に処理されるようにする必要があります。
      • プロパティ スレッドの例: プロパティの変更は、コントロールが読み取り専用の場合に実行されます。 コントロール ステートに基づいて、プロパティの変更が適切に処理されるようにする必要があります。
    • .NET ライブラリもセキュリティで保護されていることを確認するには、任意の .NET ライブラリの使用を確認する必要があります。
  • コントロール (HTML、JavaScript、CSS、サードパーティ製ライブラリ) のクライアント側の部分に関連する脆弱性は、一般的なセキュリティで保護された Web 開発原則に従う必要があります。 特定の例には、XSS の脆弱性が含まれます。
    • ユーザー データを HTML/JavaScript/CSS にレンダリングするコントロールは、軽減策が特定されている必要がある XSS 脆弱性を公開します。
    • iFrame 内の外部のコンテンツをレンダリングするコントロールは、軽減策が特定されている必要のある XSS 脆弱性を公開します。
    • サード パーティ サービスへの呼び出しを行なうコントロールは、軽減策が特定されている必要があり、クライアント チームによって直接の確認が必要です。
    • 認証を処理するコントロールには、軽減策が特定されている必要があります。

コントロール基準の詳細

このセクションでは、制御基準をさらに詳しく説明します。

基本的な使用準備

X++ ランタイム

  • FormControlAttribute 各コントロールは、クラス宣言に FormControlAttribute を指定する必要があります。 属性は、コントロールに付属しているビルド/デザイン時クラスを指定する必要があります。 属性は、HTML テンプレート ID と物理 HTML ファイル名 (リソース バンドル名) も指定する必要があります。
  • FormTemplateControl 各コントロールは、コントロール ライフサイクルに参加するために FormTemplateControl を拡張する必要があります。
  • FormProperty 各コントロールは、変更追跡システムに参加する必要がある静的に定義されたプロパティごとに FormProperties を宣言する必要があります。 サーバー側でのみ使用されるプロパティについては、FormProperty は必要ありません。
  • 新規 各コントロールは、そのプロパティがコントロールのクライアント部分とサーバー部分の間で値の変更を反映する変更追跡システムに参加するために、新規メソッドを実装する必要があります。 新規メソッド内で、各 FormProperty
  • ApplyBuild デザイン時に設定された値に基づいてコントロールを初期化するには、各コントロールで ApplyBuild メソッドを実装する必要があります。 このメソッドは、主に、設計時の値をランタイムに相当するものにコピーまたは変換するために使用されます。 ただし、すべてのデザイン時プロパティにランタイムと同等のものがある必要はなく、すべてのランタイム プロパティにデザイン時プロパティからの初期値を調達する必要もありません。
  • プロパティ ゲッター/セッター 各コントロールは、コントロールによって使用されるすべての FormProperty に対してプロパティ ゲッター/セッターを実装する必要があります。 これらのメソッドは parm メソッドでなければなりません。 したがって、getters/setters であるメソッドの場合、名前は「parm」で始まり、getter のみのメソッドの場合は「get」、setter のみの場合は「set」で始まる必要があります。 少なくとも、FormPropertyAttribute は FormPropertyKind とプロパティの名前と共にクライアントの HTML と JavaScript にアクセス可能にする必要があるため、各メソッドに提供する必要があります。

HTML

  • テンプレート ID 各コントロールは、コントロールのマークアップの最も外側の HTML 要素上の HTMLID 属性を提供する必要があります。 コントロールが実行時に読み込まれるには、この ID が FormControlAttribute に渡される ID と一致する必要があります。
  • スクリプトとスタイル シート 各コントロールは、HTML 標準 <スクリプト> および <リンク> タグを使用して他の JavaScript ファイル CSS ファイルを使用します。 これらのタグは、コントロールの HTML 定義要素の前に、HTML ファイルの先頭に配置する必要があります。 読み込む必要があるファイルに依存関係がある場合は、<スクリプト>または <リンク> 適切なタグの順序が適切であることを確認します。 最初に表示されるタグが最初に読み込まれます。 AOT リソースから JavaScript または CSS を読み込むには、サイトのルート相対パス (/Resource/Scripts または /Resources/Styles) を使用します。
  • データ バインディング各コントロールは、コントロールに含まれる HTML 要素の data-dyn-bind 属性を使用して HTML バインディング フレームワークに参加できます。 バインド属性を使用すると、HTML 要素のプロパティを、現在のデータコンテキストにある監視可能なプロパティまたは計算されたプロパティにバインドできます。

JavaScript

  • スクリプト カプセル化 各コントロールは、匿名関数では、すべての JavaScript をラップする必要があります。 この要件は、フレームワークのグローバル JavaScript 名前空間にコントロール固有のロジックが設定されないようにします。
  • ローカライズ可能な文字列 各コントロールは、コントロールの JavaScript によって使用される文字列メッセージを保存するグローバリゼーション API を使用する必要があります。 したがって、コントロールの JavaScript は、UI に表示される文字列をハードコードするべきではありません。 代わりに、JavaScript はグローバリゼーション API 経由で保存されている文字列メッセージを参照する必要があります。 グローバリゼーション・オブジェクトの文字列を HTML および JavaScript で読み込むには、$dyn.label API を使用し、ラベルの識別子を渡します。 詳細については、 ローカライズ可能なラベルを作成する を参照してください。
  • 既定値各コントロールは、JavaScript で初期化されていないプロパティの既定値を提供する必要があります。 したがって、初期化時に値が JavaScript コンストラクターに渡されるプロパティ (つまり、X++ ランタイム クラスの FormProperties) は、これらのプロパティの既定値辞書を提供する必要があります。
  • JavaScript コンストラクター 各コントロールは、コントロールの名前空間にコンストラクターを実装する必要があります。 このコンストラクターは、コントロールがクライアントにロードされたときに実行される最初のコード行です。 コンストラクターを完了した後、コンストラクターの関連付けられたオブジェクト、これは、既定のデータ コンテキストとして HTML に渡されます。
  • 基本コントロールの継承 各コントロールのコンストラクターは、基本の JavaScript コントロールクラスから「継承」する必要があります。 基本の JavaScript コントロール クラスには、各コントロールに必要な動作が含まれています。
  • 既定値を適用する各コントロールは、コントロールのプロパティに既定値を適用するために、指定されたフレームワーク関数を使用する必要があります。
  • クライアント側のプロパティ/機能を追加する各コントロールは、コントロール コンストラクターに渡されるサーバー側の FormProperties および Commands に加えて、クライアント側専用のプロパティと関数を JavaScript クラスに追加できます。 クライアント側専用のプロパティ/機能を追加するためのパターンは、この オブジェクトのローカル コピーを維持するためであり、その関数/プロパティをローカルのコピーに追加します。 コントロール コンストラクターが完了すると、追加されたすべてのプロパティ、関数、FormProperties、コマンドは、既定のデータ コンテキストとして HTML で使用可能になります。
  • 監視可能な計算されたプロパティの追加各コントロールは、クライアントの監視可能なパターンに関与するクライアント側専用のプロパティを追加できます。 監視可能なプロパティは $dyn.observable ([初期値]) 関数を使用して初期化されます。 計算されたプロパティは、$dyn.computed([function(){}]) 関数を使用して初期化されます。 コントロールは監視可能/計算されたプロパティを慎重に使用する必要があります。これらのプロパティは、誤って使用されるとパフォーマンスに重大な影響を及ぼす可能性があるためです。
  • コントロール JavaScript プロトタイプ各コントロールは、基本コントロール プロトタイプを拡張する JavaScript プロトタイプを実装する必要があります。 プロトタイプには、コントロールによって使用される「静的な」JavaScript メソッド (ローカル変数への参照を必要としないメソッド) が含まれている必要があります。

インタラクティビティ

レイアウトとサイズ変更

  • フォーム開発者がコントロールのレイアウトとサイズを決定できるようにするには、次のコードに示すように、コントロールのフォーム開発者が指定した幅と高さを $dyn.layout.sizing API を使用して設定します。 これは、すべての HTML コントロール テンプレートに適用される標準コードです。

    <div id="MyControl" data-dyn-bind="
    sizing: $dyn.layout.sizing($data)>
    </div>
    

タスク レコーダー記録サポート

コントロールは、SysTaskRecorder X++ API を使用して、コントロールのどのアクションが「記録可能」であるかを示す必要があります。

  • プロパティを使用して値の設定可能にするコントロールについては、X++ で値が設定されるときに SysTaskRecorder::addPropertyUserAction が呼び出される必要があります。 このメソッド呼び出しは、プロパティの設定を記録するようにタスク レコーダーに指示します。
  • コマンドに対して同様のメソッドが存在します (SysTaskRecorder::addCommandUserAction)。

詳細については、 コントロールに対してタスク レコーダーが生成するテキストの制御 を参照してください。

タスク レコーダー再生サポート

  • タスク レコーダーは、コントロールのプロパティやコマンドを使用してコントロールを再生します。 コントロールは、タスク レコーダーに記録するように指示するコマンドとプロパティも、コントロールの再生時にタスク レコーダーによって実行できることを確認する必要があります。 タスク レコーダーは、プロパティやコマンドの対話可能な名前に依存します。 メソッドの対話型の名前は、FormPropertyAttribute または FormCommandAttribute で指定された名前です。

タスク ガイド サポート

タスク ガイドは、タスク ガイドが指すべき DOM 要素のコントロールの JavaScript 部分を尋ねます。 すべてのコントロールは基本的なタスク ガイド サポートで既定される DOM 要素によってコントロールの最も外側の要素を継承します。

  • コントロールの JavaScript プロトタイプで getTaskGuideParams 関数を実装することによって、コントロールはタスク ガイドがポイントする必要がある場所に関する細かい詳細を提供できます。 この関数は (オプションという名前の) 引数を受け取り、この引数はターゲットという名前のプロパティを持ちます。 このターゲットプロパティは、タスクガイドが指定する必要がある jQuery 要素を受け入れます。
  • さらに、引数には、プロパティ/コマンドの名前および引数など、コントロールに対して元から記録されたアクションに関する情報が含まれます。 コントロールは、ユーザーが記録したプロパティ/コマンドに対応する DOM 要素をターゲットに供給することによって、サポートするさまざまなプロパティ/コマンドに反応することができます。
  • 高度なシナリオでは、ターゲットはオブザーバブルによっても指定されます。 コントロールは、コントロールが公開するイベントに基づいて、さまざまな DOM 要素でこのオブザーバブルを更新できます。 これは、オブザーバブル (DOM 要素を含む) でターゲットを初期化し、次にイベントを観察し、イベント ハンドラー内のコードを介して DOM 要素を更新することによって行うことができます。

タスク レコーダーのコピー/貼り付け/検証サポート

コピー、貼り付け、または検証 (主に詳細な X++ テスト目的用) のいずれかをサポートする必要のあるコントロールについては、SysTaskRecorder API は、値がコピーされ、貼り付けられ、または検証される時点でタスク レコーダーに通知するため、コントロールを有効にする静的メソッドを公開します。