Skip to main content

カスタムUIコンポーネント

このガイドで学ぶこと

Noodlの非常に強力な機能の1つは、簡単に再利用可能なコンポーネントを作成できることです。このガイドでは、再利用可能なUIコンポーネントを作成するためのいくつかの有用なパターンをカバーします。このガイドでは少しコーディングが含まれるため、Javascriptでの基本的なコーディングスキルと、Javascriptでのビジネスロジックに関する以前のガイドを読んでいることが望ましいです。

コンポーネントの入力と出力

良い再利用可能なコンポーネントを作成する鍵は、それを使用可能にする入力と出力を提供することです。ここではいくつかの良いパターンがあり、ここでそれらを概説します。スライダーと2つのラベルを持つコンポーネントを作成するシンプルな例から始めます。これがその外観です:

そしてこれがコンポーネントの内容です。これはスライダーと2つのテキストラベルを持つシンプルなUIコンポーネントです。1つのラベルはスライダーのヘッダーで、もう1つはString Formatノードと現在のValueおよびMax値を使用してフォーマットされます。

このコンポーネントのコンポーネント入力について詳しく見てみましょう。まず、コンポーネントの基本設定であるLabelMaxValue入力があります。このコンポーネント入力に関して注目すべきいくつかの点があります。Max入力を見ると、最初にNumberノードに接続され、その後String Formatノードに接続されていることがわかります。これは、Max入力がコンポーネントを使用したときにプロパティパネルで数値として表されることを保証する一般的なパターンです。コンポーネント入力は、接続されたノードと同じタイプのプロパティパネルになりますが、この場合はSliderMax(数値)とString FormatノードのMax入力(文字列)の両方に接続されています。Numberノードを経由することで、プロパティパネルがその入力に対してどの入力フィールドを表示するかを正しく認識することができます。

もう1つ注目すべき点は、Valueコンポーネント入力がSliderValue入力に接続されていることです。ほとんどのUIコンポーネントは、この場合は範囲値のように、ユーザーから何らかのデータを収集しています。そのデータも入力として公開されることが非常に重要です。これにより、データソースに適切に接続することができます。

コンポーネント出力に進むと、もちろんValueも出力として必要です。これにより、UIコンポーネントを使用してユーザーからデータを収集することができます。Changedシグナルも重要です。

warning

Changedシグナルは、ユーザーの入力があった場合に常にオンにするべきです。Value入力が変更されただけではないことを確認するためです。これにより、入力値が変更された場合に

UIコンポーネントが変更を報告しないようにします。これにより、不要なデータフィードバックループが発生することがあります。

最後に、ルートノードにいくつかの最小限のレイアウトプロパティを公開することは良いアイデアです。これにより、UIコンポーネントの使用が容易になります。

何を入力として公開するかは自由に選択できますが、ここではいくつかの推奨事項があります:

  • マージン 少なくともマージンを公開することで、コンポーネントを使用する際に余分なGroupノードが不要になります。
  • アライン コンポーネントを使用する際に再アラインメントが必要になることがよくありますので、これを入力として提供することが役立ちます。
  • ポジション 一般的ではありませんが、公開しておくと良いでしょう。

コンポーネントオブジェクト

データを扱うガイドObjectノードの使用方法を学び、UIコントロールをデータに接続するガイドでUIコントロールに接続する方法を学びました。再利用可能なUIコンポーネントを作成する際に非常に便利な別のノードがあります。それがComponent Objectノードです。このノードはObjectノードと同じように機能しますが、コンポーネントインスタンス固有であり、通常のオブジェクトのようにコンポーネントインスタンス間で共有されません。これは、UIコントロールの状態を保持する際に非常に便利です。

Segment Control UIコンポーネントの非常にシンプルな例を見てみましょう。

この例には、セグメントコントロールコンポーネントとセグメントコントロールボタンコンポーネントの2つのコンポーネントが実際に含まれています。これは、可能なオプションの配列を入力として受け入れ、配列内の各オブジェクトにはLabelValueが必要です。また、コントロールの現在の選択されたValueも入力として受け入れます。これは配列内の値の1つに対応する必要があり、そのボタンが選択されているように表示されます(ラジオボタンのように)。

ここでは、Component Objectノードを使用して現在のSelected Valueを保存し、それをValue出力としても渡している方法を見ることができます。後でこれがどのように使用されるかを見てみましょう。オプション入力配列は、Repeaterノードのアイテムとして直接使用されます。リピーター内のテンプレートとして使用されるセグメントコントロールボタンコンポーネントを詳しく見てみると、魔法が起こる場所がわかります。

簡単に説明しましょう:

  • Objectノードは、ボタンにLabelを接続するために使用されます。したがって、リピーターによって作成された各ボタンに正しいラベルが付けられます。
  • ここで、Set Parent Component Object Propertiesノードという新しいアクションノードを紹介します。これは、コンポーネントオブジェクトのプロパティを設定するために使用されます。しかし、このコンポーネントインスタンスのコンポーネントオブジェクトではなく、代わりに最も近い視覚的親のコンポーネントオブジェクトです。この場合(このコンポーネントがリピーターのテンプレートとして使用されているため)、セグメントコントロールコンポーネントになります。つまり、リピーター内の各セグメントコントロールボタンコンポーネントは、クリックされると、そのValueComponent ObjectSelected Valueとして設定します。
  • 現在のSelected ValueとこのセグメントコントロールボタンのValueを比較するために、Parent Component Object

使用して、Functionノードでそれを行います。そのコードは以下の通りです:

if(Inputs.SelectedValue == Inputs.MyValue)
Outputs.Variant = "セグメントコントロールボタン選択"
else
Outputs.Variant = "セグメントコントロールボタン"
  • 次に、Functionによって選択されたVariantボタンVariantになります。ボタンの2つの異なるVariantをそれぞれその名前で作成しているので、選択された場合とそうでない場合にボタンがどのように見えるかを設計できます。スタイルバリアントについては、このガイドで詳しく学ぶことができます。
  • 最後に、ボタンからのClickシグナルをこのコンポーネントからのComponent Outputとして送信します。これにより、親コンポーネント内のRepeaterノードからそのシグナルを使用することができます。

Component ObjectおよびParent Component Objectノードと、プロパティを設定するためのアクションノード、Set Component Object PropertiesおよびSet Parent Component Object Propertiesは、再利用可能なUIコンポーネントを構築する際に非常に便利です。UIコンポーネントの状態はこれらに保存することをお勧めします。

状態管理

UIコンポーネントが作成されたときに初期化する必要がある場合があります。その場合、ルートUI要素(通常はGroupノード)からのDid mountシグナルを使用できます。

Component ObjectおよびParent Component Objectには、FunctionおよびScriptノードから次のようにアクセスできます:

Component.Object.MyValue = "こんにちは" 
Component.Object["選択された値"] = "スペースを含むプロパティにはこれを使用します"

Component.ParentObject.MyValue = "これも機能します"

これは、UIコンポーネントが作成されたときにComponent Objectを初期化するのに最適な場所です。

ここで、もう1つ興味深い例を見てみましょう。これはマルチチェックボックスグループの例です。2つの配列を入力として受け取り、1つはすべての可能なオプションを持ち、各オブジェクトにはValueLabelが必要です。もう1つの配列は値で、この配列にはValueのみを含むオブジェクトが含まれます。したがって、複数のオプションを選択でき、セグメントコントロールのように1つだけではありません。これは少し複雑なので、詳細には触れませんが、以下の例をチェックして、いくつかの詳細を見てみましょう。

マルチチェックボックスグループコンポーネントのノードを詳しく見ると、次のようになります:

ここでは、オプションまたは選択の入力が変更された場合にFunctionノードが実行されることがわかります。そのノードのコードは次のとおりです:

if(!Inputs.Options) return // オプションがなければ何もできません

Component.Object.Checkboxes = Inputs.Options.map(o => Noodl.Object.create({
id:Component.Object.id+'-'+o.Value,
Value:o.Value,
Label:o.Label || o.Value,
Checked:Inputs.Selection!==undefined && !!Inputs.Selection.find(s => s.Value === o.Value)
}))

これにより、Component ObjectCheckboxesという名前の新しいオブジェクトの配列が作成され、それらは値とラベルを取得し、Checkedプロ

パティはその値が選択内に表現されている場合にtrueになります。この配列は、すべてのコンポーネントを表示するためにRepeaterノードで使用されます。この関数がオプションまたは選択が変更された場合に再実行されることが重要です。これにより、UIコントロールが常に入力に対応する正しい状態を表示するようになります。

note

オブジェクトのidを設定します。これにより、配列が変更されるたびにRepeaterが新しいアイテムを作成しないようになります。これによりパフォーマンスが向上します。

もう1つ注目すべき点は、Selection入力がComponent Objectに渡され、そのまま対応する出力に渡されることです。これも非常に一般的です。

最後に、選択がユーザー入力によって変更された場合に実行されるFunctionノードがあります。上記のセグメントコントロールコンポーネントと同様に、このコンポーネントはRepeaterノードから送信されます。このコンポーネントでは、現在チェックされているオブジェクトをフィルタリングして、それらのオブジェクトのValueプロパティをフィルタリングすることによって、現在のSelectionComponent Objectで更新します。

Component.Object.Selection = Component.Object.Checkboxes.filter(o => o.Checked).map(o => ({Value:o.Value}))

マルチチェックボックスグループアイテムコンポーネントを見ると、非常に基本的であることがわかります。これは単に、Checkboxes配列に作成したオブジェクトのCheckedLabelに対応するチェックボックスです。チェックボックスが更新されると、オブジェクトのChecked値を更新し、変更を報告します。

以上です。これで、マルチチェックボックスコンポーネントを作成するために必要なすべてのことを説明しました。このパターンは、マルチ選択を持つあらゆる種類のUIコンポーネントを作成するために使用できます。