Polymer2 で <input> の値を「親エレメントの値と」バインドする
   2 min read

Polymer2 で の値をバインドするmy-input なるカスタムエレメントを作成しました。<input>の入力値をそのまま表示するだけのエレメントです。

1
2
3
4
5
6
7
<dom-module id="my-input">
  <template>
    <input type="text" value="{{text::input}}" />
    [[text]]
  </template>
  ...
</dom-module>

さて、この入力値を受け取れるよう、親エレメントを次のように作成しました。

1
2
3
4
5
6
7
<dom-module id="my-parent">
  <template>
    <my-input text="{{parentText}}"></my-input>
    [[parentText]]
  </template>
  ...
</dom-module>

そして<input>に値を入力してみると…親に反映されない。

いろいろ試行錯誤してみた所、親エレメント側にも ::input を足して

1
2
3
4
5
6
7
<dom-module id="my-parent">
  <template>
    <my-input text="{{parentText::input}}"></my-input>
    [[parentText]]
  </template>
  ...
</dom-module>

とすれば反映されるようになりました。けど、これはどうなんだろう?
子(my-inputエレメント)は、まあ自分が<input>を扱っているのを知っているから良いとして、親(my-parentエレメント)が子の事情を考慮して実装しないといけないとは。


これの答えはここでした。

てっきりカーリーブラケット{{}}は、子エレメントへも親エレメントへも自動で反映してくれるものだと思っていたのですが、正確には、「親エレメントへも反映できる」だけで、デフォルトでは反映してくれないようです。

Automatic, which allows upward (target to host) and downwards (host to target) data flow. Automatic bindings use double curly brackets ({{ }}):

notify. A notifying property supports upward data flow. By default, properties are non-notifying, and don’t support upward data flow.

そんなわけで、notifyを明示的にtrueに設定してやる必要がありました。

子エレメント(今回の場合だとmy-input)のプロパティ定義で次のようにすれば良いことになります。

冒頭に書いたような、親エレメント(今回の場合はmy-parent)に::inputは必要ありません。

1
2
3
4
5
6
7
8
      static get properties() {
        return {
          text:{
            type: String,
            notify: true
          }
        }
      }