attributeChanged 不会在 2 路数据绑定聚合物上被触发
attributeChanged not getting fired on 2 way data binding polymer
在我的聚合物元素中,我有 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
.
这是预期的行为吗?有没有办法为 2 路数据绑定调用空白的 Changed 方法?
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 中,这是设置 'myAttributeChanged' 函数的地方
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"。有趣的是,这实际上不必是在聚合物元素中任何地方定义的属性才能起作用,但那是另一回事。
在我的聚合物元素中,我有 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
.
这是预期的行为吗?有没有办法为 2 路数据绑定调用空白的 Changed 方法?
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 中,这是设置 'myAttributeChanged' 函数的地方
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"。有趣的是,这实际上不必是在聚合物元素中任何地方定义的属性才能起作用,但那是另一回事。