Polymer 1.x:Obervers bug?修复或解决方法?

时间:2015-12-02 10:45:52

标签: polymer polymer-1.0

首先让我说,我90%肯定这是Polymer观察员系统的错误。

进行以下测试并注意以下意外行为:

测试程序

  1. Open this JSBin
  2. 切换<paper-toggle-button>
  3. 请注意,changes变量按预期增加。
  4. <paper-input>字段中输入任何文字。
  5. 请注意changes变量 按预期增加。
  6. 再次切换<paper-toggle-button>
  7. 请注意,changes变量现在按预期增加。
  8. 注意我也观察到<paper-dropdown-menu><paper-toggle-button>一样的问题,但为了简洁起见,在此问题中省略了它。

    问题

      
        
    • 这里发生了什么事?
    •   
    • 这是一个错误吗?
    •   
    • 有解决方法或修复方法吗?
    •   
    http://jsbin.com/saxewimowu/edit?html,output
    <html>
    <head>
      <title>My Element</title>
      <script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
      <script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
      <base href="http://element-party.xyz/" />
      <link rel="import" href="all-elements.html" />
    </head>
    <body>
      <dom-module id="my-element">
        <template>
          <paper-input value="{{str::input}}"></paper-input><br />
          <paper-toggle-button checked="{{bool}}"></paper-toggle-button><br />
          <br />changes:<span>[[num]]</span><br />      
          <br />str: <span>[[str]]</span><br />
          <br />bool:<span>[[bool]]</span><br />
        </template>
        <script>
          (function() {
            Polymer({
              is: 'my-element',
              observers: [
                'inputChanged(str, bool)'
              ],
              inputChanged(a, b) {
                if(! this.num){
                  this.set('num', 1);
                } else {
                  this.set('num', (this.num + 1) );
                }
              }
            });
          })();
        </script>
      </dom-module>
      <my-element></my-element>
    </body>
    </html>
    

3 个答案:

答案 0 :(得分:4)

两个属性的值都不同于undefined(我猜或null)。 输入文本并单击切换后,每个更改都会打印A。 要解决为您的属性分配默认值。

我添加了

      properties: {
        str: {
          type: String,
          value: ''
        },
        bool: {
          type: Boolean,
          value: false
        }            
      },

你的元素,我不能再重现你的问题了。

答案 1 :(得分:2)

解决方法是单独观察道具。

 (function() {
    Polymer({
      is: 'my-element',
      properties: {
        str:        {
          type:       String,
          notify:     true,
          observer:   '_somethingChanged'
        },
        bool:       {
          type:       Boolean,
          notify:     true,
          observer:   '_somethingChanged'
        }
      },
      _somethingChanged: function(evt) {
        // At this point, evt contains infos about what changed. Eg path and value.
        console.log('Something changed');
      },
    });
  })();

另一种解决方法是制作同一属性的strbool部分(名为foo的对象)并观察foo.*

  (function() {
    Polymer({
      is: 'my-element',
      properties: {
        foo:        {
          type:       Object,
          notify:     true,
          value:      function(){
            return {
              str:     'Default',
              bool:    false
            }
          }
        },
      },
      observers: [ '_somethingChanged(foo.*)' ],
      _somethingChanged: function() {
        // At this point, evt contains infos about what changed. Eg path and value.
        console.log('Something changed');
      },
    });
  })();

答案 2 :(得分:1)

为了完整起见,我将添加源代码和this link to the JSBin of the accepted answer and working solution

http://jsbin.com/pufalegofe/1/edit?html,output
<html>
<head>
  <title>My Element</title>
  <script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents-lite.js"></script>
  <script data-require="polymer@*" data-semver="1.0.0" src="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html"></script>
  <base href="http://element-party.xyz/" />
  <link rel="import" href="all-elements.html" />
</head>
<body>
  <dom-module id="my-element">
    <template>
      <paper-input value="{{str::input}}"></paper-input><br />
      <paper-toggle-button checked="{{bool}}"></paper-toggle-button><br />
      <br />changes:<span>[[num]]</span><br />      
      <br />str: <span>[[str]]</span><br />
      <br />bool:<span>[[bool]]</span><br />
    </template>
    <script>
      (function() {
        Polymer({
          is: 'my-element',
          properties: {
            str: {
              type: String,
              value: ''
            },
            bool: {
              type: Boolean,
              value: false
            }            
          },
          observers: [
            'inputChanged(str, bool)'
          ],
          inputChanged: function(a, b) {
            if(! this.num){
              this.set('num', 1);
            } else {
              this.set('num', (this.num + 1) );
            }
          }
        });
      })();
    </script>
  </dom-module>
  <my-element></my-element>
</body>
</html>