Node-REDにEditableListという、データを追加していくことができるリストの機能があります。
(https://nodered.jp/docs/api/ui/editableList/ )
これですが、実際使うにはドキュメントに書かれていないことが結構あり、ドキュメントだけをみて開発を進めていくのはしんどいものがあった。
実際に使われているノードを参考にし、なんとか動くところにまで漕ぎ着けたけど、再度やるときにつまづきそうなので書き残しておきます。
参考にしたノードは以下です
- https://github.com/node-red/node-red/blob/master/packages/node_modules/%40node-red/nodes/core/function/10-switch.html
- https://github.com/nec-baas/node-red-contrib-nec-baas/blob/master/nebula-object-storage.html
注意するポイント
特にハマったのは以下のポイント
-
oneditprepareとoneditsave両方を使う必要がある - EditableListは
input type="text"で作ったインプットのように自動でデータの保持、表示などは行ってくれない - defaultの名前とid名のルールに従わないと、デプロイボタンが押せない(データ保持ができない)
Node-REDのUIを作ってると、なんか知らんけどデータが保持されて、データが挿入されていたりしますが、それらはEditableListには適用されません。
UIのAPIとして用意されていますが、あくまでUIの提供だけで、その他の実装は自分で頑張れが基本になっています。
設置すりゃなんとかなるだろみたいな気持ちでいると**「あれ、なんで動かないの」**ってことになります。
ではそれぞれについて説明していきます。
oneditprepareとoneditsave両方を使う必要がある
oneditprepareとは、「on edit prepare」、oneditsaveは「on edit save」が区切りなしになったものです。
前者はedit画面が表示されたときに実行され、後者は「完了」ボタンが押されたときに実行されます。
なぜどちらとも必要かというと、
oneditprepareでUIの作成や、既存データの表示
oneditsaveで入力されたデータの保持
を行う必要があるからです。
データの保持と表示のしくみ
コードを参考にしながら説明していきます。
以下の「AddItem」ではEditableListに行を追加したときにのコードが書かれています
上記でいう「UIの作成」です
https://github.com/nec-baas/node-red-contrib-nec-baas/blob/9dd14d37ac6fc88df6ae8662547d702c10587525/nebula-object-storage.html#L201
そして以下の場所で
データがあれば、データ行を作るよう指示しています
https://github.com/nec-baas/node-red-contrib-nec-baas/blob/9dd14d37ac6fc88df6ae8662547d702c10587525/nebula-object-storage.html#L277
そして、既存データがあった場合は以下の場所でデータ挿入を行っています
https://github.com/nec-baas/node-red-contrib-nec-baas/blob/9dd14d37ac6fc88df6ae8662547d702c10587525/nebula-object-storage.html#L248
そしてデータ保持を行っているのは以下の場所です
oneditsaveの最後の行でnode.rules.push(r);をして、データを保持しています。
https://github.com/nec-baas/node-red-contrib-nec-baas/blob/9dd14d37ac6fc88df6ae8662547d702c10587525/nebula-object-storage.html#L282
実際の操作の流れでみてみる
- ユーザがノードの編集画面を開く。このとき
oneditprepareが実行される - ユーザが行を追加。
AddItemが実行されて、ユーザが入力できる行が生まれる - ユーザがデータを入力
- ユーザが完了ボタンを押します。このとき
oneditsaveが呼ばれてデータを保持 - 再びユーザが編集画面を開く
-
oneditprepareが実行され、既存データがあるのでAddItemをその個数分叩く処理が実行される - 追加された行に既存データが挿入される
という流れになります。
行ったり来たりして少し面倒ですが、保持と表示の役割に分かれて動いていることを理解すると結構わかりやすくなります。
defaultの名前とid名のルールに従わないと、デプロイボタンが押せない(データ保持ができない)
これはいまいちまだルールが理解できていないんだけど
EditableListを使う場合以下のように
divには node-input-xxxxxxx-container-row
EditableListになるolには node-input-xxxxxxx-container
と名付ける。
<div class="form-row node-input-rule-container-row"><!-- -row がある -->
<ol id="node-input-rule-container"></ol><!-- -row が無い -->
</div>|
また、defaultの値には
xxxxの複数形となる値を入れる
defaults: {
name: { value:"object"},
bucketName: { value: ""},
isClause: { value: false},
rules: { value:[{t:"eq", v:""}]}, // ここ! rule"s"になってる
operator: { value: "AND"},
sortKey: { value: ""},
sortType: { value: "ASC"},
skipCount: { value: 0},
limit: { value: 100},
projection: { value: ""}
},
こうすることできちんと認識され、デプロイボタンが作動するようになる。
rulesがruleの場合は動作しなかったので注意が必要。
データの取得方法
jsファイルからは、configから代入したプロパティ名で取得が可能です。
仮に、以下のようなfunctionを書いていて、htmlではnode.listsに代入していたた場合は
config.listsでデータへのアクセスができます。
function HogehogeCreateNode(config) {
config.lists //とれた!
}
まとめ
最低限の実装はここまでのものを注意すれば作ることができました。
他にも見た目がーとかいろいろあるとはおもいますが、まずは動くことが大事!
これからノードを作る人の参考になれば幸いです。では!