0

私のポリマー要素には、attributeChangedメソッドがあります

Polymer('my-tag', {
  //some code
  attributeChanged: function(attrName, oldVal, newVal) {
    console.log(attrName, 'old: ' + oldVal, 'new:', newVal);
  },
  myAttributeChanged: function(oldVal, newVal){
    console.log("myattribute changed", 'old: ' + oldVal, 'new:', newVal);
  }
});

これは、手動で属性を変更すると呼び出されます。

tag.setAttribute('myAttribute',"wow");

これは、2 方向のデータ バインディングによって属性を設定すると呼び出されません。

 <my-tag id="myTagId" myAttribute="{{wowAtrribute}}"></my-tag>
//in script section
this.wowAttribute = "wow";

attributeChangedを呼び出すだけで、これはメソッドを呼び出しませんmyAttributeChanged

これは予想される動作ですか?双方向のデータバインディングのために呼び出された空白の Changed メソッドを取得する方法はありますか?

4

1 に答える 1

2

TLDR: poylmer.js と CustomElements.js を掘り下げてみると、実際にどのように動作するかを確認できます (彼らの意図ではないかもしれませんが、少なくともコードでは)。

CustomElements.js には、setAttribute 関数と removeAttribute 関数を一緒にオーバーロードして、changeAttributeCallback 関数を呼び出すこれらの関数がいくつかあります。

  function overrideAttributeApi(prototype) {
    if (prototype.setAttribute._polyfilled) {
      return;
    }
    var setAttribute = prototype.setAttribute;
    prototype.setAttribute = function(name, value) {
      changeAttribute.call(this, name, value, setAttribute);
    };
    var removeAttribute = prototype.removeAttribute;
    prototype.removeAttribute = function(name) {
      changeAttribute.call(this, name, null, removeAttribute);
    };
    prototype.setAttribute._polyfilled = true;
  }
  function changeAttribute(name, value, operation) {
    name = name.toLowerCase();
    var oldValue = this.getAttribute(name);
    operation.apply(this, arguments);
    var newValue = this.getAttribute(name);
    if (this.attributeChangedCallback && newValue !== oldValue) {
      this.attributeChangedCallback(name, oldValue, newValue);
    }
  }

Polymer.js では、'attributeChanged' は効果的に 'attributeChanged' としてエイリアス化されます。したがって、コールバックが使用されるのは、setAttribute または removeAttribute を使用するときだけです。

個々の属性については異なりますが。これは、polymer.js では、これらの 'my​​AttributeChanged' 関数がセットアップされる場所です。

  inferObservers: function(prototype) {
      // called before prototype.observe is chained to inherited object
      var observe = prototype.observe, property;
      for (var n in prototype) {
        if (n.slice(-7) === 'Changed') {
          property = n.slice(0, -7);
          if (this.canObserveProperty(property)) {
            if (!observe) {
              observe  = (prototype.observe = {});
            }
            observe[property] = observe[property] || n;
          }
        }
      }
    } 

したがって、基本的に、「Changed」で終わるプロパティに対して、ポリマーは「Changed」が進行するものに対してオブザーバーを設定します。興味深いことに、これが実際に機能するためにポリマー要素のどこかに定義された属性である必要はありませんが、それは別の話です。

于 2015-04-20T19:42:47.347 に答える