LoginSignup
2
2

More than 5 years have passed since last update.

Node-redのmustacheテンプレート中でeval的な事をしたい時はLambda式を使うと嬉しいです

Posted at

前提

Node-redでHTMLを動的に生成したい場合に一応Mustacheテンプレートまでは使って見たけれど、微妙に痒いところに手が届かないという人向けです。

状況

例えば、以下のようなPayloadを表にしたいとします。

{
    "payload": [
        {
            "serial": 1,
            "lank": "bronze",
            "lastname": "tanaka",
            "firstname": "taroh",
            "phone": "090-0000-0000"
        },
        {
            "serial": 2,
            "lank": "gold",
            "lastname": "suzuki",
            "firstname": "jiroh",
            "phone": "090-0000-0001"
        },
        {
            "serial": 3,
            "lank": "silver",
            "lastname": "yamada",
            "firstname": "hanako",
            "phone": "080-0000-0000"
        }
    ]
}

上記のJSONだった場合、mustacheテンプレートは

{{#payload}}
  <tr>
    <td>{{serial}}</td>
    <td>{{lank}}</td>
    <td>{{lastname}}</td>
    <td>{{firstname}}</td>
    <td>{{phone}}</td>
  </tr>
{{/payload}}

とやれば、(前後のtableタグと一行目はまぁどこかに書いてあるとして)

serial lank lastname firstname phone
1 bronze tanaka taroh 090-0000-0000
2 gold suzuki jiroh 090-0000-0001
3 silver yamada hanako 080-0000-0000

みたいな表になるためのHTMLが出来てくるわけです。
ここまではまぁ普通の便利な使い方です。

ここで、例えばLankが、外部キー的になってた場合どうするのか?

つまり、

serial lank lastname firstname phone
1 3 tanaka taroh 090-0000-0000
2 1 suzuki jiroh 090-0000-0001
3 2 yamada hanako 080-0000-0000
serial lankname
1 gold
2 silver
3 bronze

みたいなデータ構造になるってわけです。まぁ普通はこういう構造の方が多いですよね。
で、そのときにどうやってスマートに描画するか?
そこでLambda式を使います。

まず、templeteノードよりも前にFunctionノードを用意して、

msg._render = function(){
    return function(text, render){
        return render("{{" + render(text) + "}}") ;
    }
};
return msg;

としておきます。
あと、前提となるデータとして

{
    "payload": [
        {
            "serial": 0,
            "lank": 2,
            "lastname": "tanaka",
            "firstname": "taroh",
            "phone": "090-0000-0000"
        },
        {
            "serial": 1,
            "lank": 0,
            "lastname": "suzuki",
            "firstname": "jiroh",
            "phone": "090-0000-0001"
        },
        {
            "serial": 2,
            "lank": 1,
            "lastname": "yamada",
            "firstname": "hanako",
            "phone": "080-0000-0000"
        }
    ]
}

ってのと(さっきとはlankの中身が変わってます)、それに加えて

{
    "lanklist": [
        {
            "serial": 0,
            "lankname": "gold"
        },
        {
            "serial": 1,
            "lankname": "silver"
        },
        {
            "serial": 2,
            "lankname": "bronze"
        }
    ]
}

というのも用意しておきます。
その状態で、mustacheを以下のようにします。

{{#payload}}
  <tr>
    <td>{{serial}}</td>
    <td>{{#_render}}lanklist.{{lank}}.lankname{{/_render}}</td>
    <td>{{lastname}}</td>
    <td>{{firstname}}</td>
    <td>{{phone}}</td>
  </tr>
{{/payload}}

このlanklist.{{lank}}.lanknameのところを{{#payload}}のリストとして評価すると、最初はlanklist.0.lanknameというテキストになります。それを{{#_render}}の箇所でlambda式に突っ込むわけです。
中身はrender("{{" + render(text) + "}}")なので、つまりrender("{{lanklist.0.lankname}}")を評価せい、という事で、めでたくgoldという文字列に置き換わってくれるという事になります。

以上ですが、、

ぶっちゃけ、今回の実装であればlanklistのserialは管理上の為だけで、無いなら無いでもOKのはずなのです。。。
JSONata的な検索ができるんならば、別な表現も出来そうですね。。
まぁその内良いアイデアが浮かぶと思いますので、その時までは一旦これで勘弁してください。。

では。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2