動的フォームにおける条件付きタスク


TL;DR
We have support for conditional behaviors in @myndpm/dyn-forms documented at mynd.dev and we are able to provide them easily like the Controls, Validators, AsyncValidators, etc.


複雑なフォームユースケースでは、いくつかのコントロールは他のフォームコントロールの値やステータスに直接依存します.次に、カスタム動作を実装しますhiding 別のコントロールが何らかの値を持つフィールドdisabling 複雑な条件などによって異なります.
これをサポートするために、我々は追加しましたMatchers and Conditions , これはValidators and AsyncValidators このシリーズの前の章で見たように.コードから初期のアイデアを取得する場合は、このチェックを行うことができますsource file そしてreal use-case demo .

ディントレノデス
各動的制御は、フォーム階層でこの点のデータを保持する構成されたノードサービスインスタンスを持っています.これはAPI そして、必要に応じてカスタマイズされた方法でフォームを操作するデータ.
ノードはcontrol フォームインスタンスparams オブジェクト、いくつかのユーティリティメソッドquery or select 親と子のコントロール、視認性を操作します.我々は、条件、matchersおよび他のカスタムハンドラの中でこのノードを使用します.

条件
特別な条件に合うように、1つ以上の条件を定義する必要があります.AND ) または1OR ) それらのうちの我々は、特定のタスクを実行する果たしている.条件関数型は以下の通りです.
interface DynControlConditionFn {
  (node: DynTreeNode): Observable<any>;
}
これは、条件が満たされるたびに真の値をストリームします.たとえば、特定のコントロールが期待値を持っているかどうかを確認できます.
(node: DynTreeNode) => {
  return node.query('specific.control').valueChanges.pipe(
    map(controlValue => controlValue === 'xValue'),
  );
}
必要な演算子でこれらの条件に参加できます.AND | OR ) 我々のユースケースのために、そして、特定のMatcher .

マッチャー
我々は、我々が実行したいMatchersで我々の要求を定義しますwhen すべてまたは単一の条件が満たされます.
match: {
  matchers: ['DISABLE'], // one or more matchers
  when: [{
    // the library provides a DEFAULT condition handler
    // to process path, value and negation
    path: 'other.field',
    value: 'expectedValue'
  }]
}
the DISABLE Matcherは図書館に含まれていますENABLE , SHOW , HIDE (表示: None )INVISIBLE (可視性:隠し).
つのmatcherは、フォーム階層構造の作業を実行する機能から成るそのためには、DynTreeNode インスタンス
interface DynControlMatcherFn {
  (args: {
    node: DynTreeNode;
    hasMatch: boolean;
    firstTime: boolean;
    results: any[];
  }): void;
}
例えば、DISABLE matcherは、指定した条件が満たされたときにフォームコントロールに動作します.
{
  id: 'DISABLE',
  fn: (): DynControlMatcherFn => {
    return ({ node , hasMatch }) => {
      hasMatch ? node.control.disable() : node.control.enable();
    }
  }
},

先進のもの
この条件付き処理により、追加の論理演算を行うことができますnegate つまたはすべての条件の結果、我々は逆さまに条件を再生し、我々の要件の最も簡単な仕様を持つことができます.

マッチャーの例
たとえば、いくつかの選択を除いて、すべてのオプションのmatcherを実行したい場合.OR 他の条件がなければ、いくつかの既知の値を使用してその要件を定義することができます.
match: {
  matchers: ['MyMatcherID'],
  operator: 'OR', // the operator is AND by default
  when: [
    {
      path: 'selectorName',
      value: ['A', 'B', 'C'] // this will check if selectorName.value is IN this array
    },
    {
      path: 'other.control',
      value: 'anotherValue'
    },
  ],
  negate: true
}
仕掛けは受け取るhasMatch: true 指定されたリストに値がない場合.
また、カスタムでMatcher工場を提供できることに注意してくださいid ライク'MyMatcherID' 以下のセクションの条件で行います.

コンディションファクトリー
我々は工場を登録することができますidfn バリデータを実行し、configオブジェクト内でパラメータ化します.
export interface DynControlCondition {
  id: string;
  fn: (...args: any[]) => DynControlConditionFn;
}
覚えてDynControlConditionFn 返り値Observable<boolean> したがって、次のようなカスタム条件を実装して提供できます.
const conditions = [{
  id: 'MyConditionId',
  fn: (...args: any[]) => { // Factory
    return (node: DynTreeNode) => { // Condition
      return node.control.valueChanges.pipe(map(...));
    }
  }
}];

@NgModule({
  imports: [
    DynFormsModule.forFeature({ conditions });

条件設定
これらの方法でカスタム条件を使用できます.
// inline function
when: [
  (node: DynTreeNode) => {
    // manipulate the form via DynTreeNode
  }
]

// factory ID without arguments
when: [
  'MyConditionId',
]

// parametrized factory
when: [
  ['MyConditionId', args],
]

// or declarative inline config
when: [
  {
    condition: 'MyConditionId',
    path: 'other.control', // path is the only mandatory field in this format,
    param1: 'anyValue', // the whole object will be passed to your DynControlConditionFn
  },
]
最後の表記法では、Configオブジェクト全体が工場に渡されますDEFAULT 条件ハンドラはpath , value and negate 設定値.
注意:value が設定されている場合、DEFAULT ハンドラの出力true 毎回設定path 制御値の変更
id: 'DEFAULT',
fn: ({ path, value, negate }): DynControlConditionFn => {
  return (node: DynTreeNode): Observable<boolean> => {
    if (value === undefined) {
      return node.query(path).valueChanges.pipe(mapTo(true));
    }
    ...
  }
}

結論
我々は、詳細のほとんどをカバーしているMatchers and Conditions , そして、どのように1つまたは多くの条件を設定することができますので、それらの1つまたはすべてが満たされると、彼らはDynTreeNode API.
あなたがこの読書の後に考えを持っているならば、角のアプリでこのライブラリを使用した後に、我々と共有してください!
あなたはrequest features そして、我々に加わってくださいdiscussions .
/ps .私たちは採用しています!