こういうCustom Element <test-01>があります

test-01.html

<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html"/>

<polymer-element name="test-01" attributes="">
  <template>
    <h1>{{ obj.value }}!</h1>
    <paper-button on-click="{{ add }}">add</paper-button>
  </template>
  <script>
    (function () {
      Polymer({
        obj: {
          value: "ABC"
        },
        add: function () {
          this.obj.value += "1";
        }
      });
    })();
  </script>
</polymer-element>

ボタンを押すとaddが叩かれて、obj.valueを変更します。バインドされてるので<h1>中の表示もリアルタイムに更新されます。

これを複数個使うと、なぜかすべての<test-01>が同じ動きをします

index.html

<!doctype html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <title>polymer sandbox</title>
    <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
    <link rel="import" href="elements/test-01/test-01.html">
  </head>
  <body unresolved>
    <test-01></test-01>
    <test-01></test-01>
    <script src="scripts/app.js"></script>
  </body>
</html>

実際に動かしたものがこちら

01

バインド対象を文字列の変数にしてみます

<polymer-element name="test-01" attributes="">
  <template>
    <h1>{{ obj }}!</h1>
    <paper-button on-click="{{ add }}">add</paper-button>
  </template>
  <script>
    (function () {
      Polymer({
        obj: "ABC",
        add: function () {
          this.obj += "1";
        }
      });
    })();
  </script>
</polymer-element>

すると正常に動きます

02

前者で起こっていることの可能性としては

  • objが共有されている(like a static variable)
  • すべての<test-01>on-clickイベントが発火している

の2つが考えられますが、addconsole.log仕込んでみたところ、1回しか呼び出されてませんでした。

objが共有されるのって正しい挙動なんでしょうか?API developer guide - Polymer見てもこの書き方なら要素ごとのプロパティとして宣言されると思うんですけど、誰かPolymerやWebComponentsに詳しい方知ってたら教えてください