6589


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

test-01.html

[code]

    <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>
    
[/code]

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

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

index.html

[code]

    <!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>
    
[/code]

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

![01](https://i.stack.imgur.com/vwnyV.gif)

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

[code]

    <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>
    
[/code]

すると正常に動きます

![02](https://i.stack.imgur.com/iLjxk.gif)

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

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

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

`obj`が共有されるのって正しい挙動なんでしょうか？[API developer guide -
Polymer](https://www.polymer-
project.org/docs/polymer/polymer.html#propertiesmethods)見てもこの書き方なら要素ごとのプロパティとして宣言されると思うんですけど、誰かPolymerやWebComponentsに詳しい方知ってたら教えてください


CC BY-SA 3.0
2015-02-16T14:50:57.337
6587
2015-02-16T19:13:03.883
2015-02-16T15:00:14.643
4978
4635
question
javascript polymer web-component
Polymer.jsでオブジェクトのメンバをバインドすると何故かstaticになるのはバグ？


確か Polymer() 内でのオブジェクトや配列は共有状態になり、  
created: のコールバックで初期化する必要があったはずです。

[code]

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

また、今回の場合は publish でも回避することができます。

[code]

    <polymer-element name="test-01" attributes="">
      <template>
        <h1>{{ obj1 }}!</h1>
        <h2>{{ obj2 }}!</h2>
        <paper-button on-click="{{ add1 }}">add1</paper-button>
        <paper-button on-click="{{ add2 }}">add2</paper-button>
      </template>
      <script>
        (function () {
          Polymer({
            publish: {
              obj1: "ABC",
              obj2: "EFG"
            },
            add1: function () {
              this.obj1 += "1";
            },
            add2: function () {
              this.obj2 += "1";
            }
          });
        })();
      </script>
    </polymer-element>
    
[/code]


CC BY-SA 3.0
2015-02-16T19:13:03.883
6589
2015-02-16T19:13:03.883
8326
6587
answer