任何给定属性的更改后的事件处理程序似乎都会触发,即使是在第一次使用该属性的默认值以外的值初始化元素时也是如此。
例如,假设我有以下自定义的聚合物元素。
<polymer-element name="some-thing" attributes="name">
<script>
Polymer({
name: 'John Jacob Jingleheimer Schmidt',
nameChanged: function (oldValue, newValue) {
console.log('name changed from ' + oldValue + ' to ' + newValue);
}
});
</script>
</polymer>
当我在标记中包含这个元素时,即使我不是在概念上"更改"值,而是在初始化它,名称更改的事件处理程序也会立即启动
<some-thing name="Peter Peter Pumpkin Eater"></some-thing>
我只希望在外部代码修改元素name属性的值时触发事件处理程序。有没有一种方法可以将事件处理程序设置为以这种方式运行?
您应该检查oldValue的类型以忽略第一个赋值:
Polymer({
/* ... */
nameChanged: function (oldValue, newValue) {
if ('undefined' !== typeof oldValue) {
// ...
}
});
当name的值更改时,您可以使用if语句检查它是否有值。
nameChanged: function () {
if (this.name) {
// only ran when there is a value
}
}
或者,您可以检查newValue。我从来没有试过这个。
if (newValue) {
// only ran when there is a value
}
可能有一种更清洁的方法,但这对我有效。
edit:也可以使用created函数来设置name的值,这样可以防止它触发2次。试试类似的东西。
created: function () {
this.name = this.name || "Peter Cottontail";
}
再次编辑:将就绪函数更改为已创建函数。我认为ready函数仍然会导致值更改2次。
首先,请避免覆盖现有的属性名称,如name
、title
等。这在不同的浏览器中以多种方式带来了很多问题。我将使用someName
作为下面的属性名称。
一般来说,你是否有一个属性明确指定在你的光DOM与:
<some-thing someName="Peter Peter Pumpkin Eater"></some-thing>
事件将被激发,因为名称已更改。根据名称是默认名称这一事实,您可以有一些逻辑:
if (this.someName === 'John Jacob Jingleheimer Schmidt') {
// we are on initials, let’s do nothing here
}
这就是事件要被触发的原因。无论您是否仍然希望抑制为lightDOM中指定的值触发这些事件,都可以使用以下工作组:
<polymer-element name="some-thing" attributes="someName">
<script>
Polymer({
someName: 'John Jacob Jingleheimer Schmidt',
isDomReady: false, // will use this to prevent onSomeNameChanged
someNameChanged: function (oldValue, newValue) {
if(!this.isDomReady) return; // skip, we are not yet initialized
console.log('name changed from ' + oldValue + ' to ' + newValue);
},
domReady: function() {
this.isDomReady = true;
this.async(function() { this.someName = 'Humpty Dumpty' });
}
});
</script>
</polymer-element>
//⇒ name changed from Peter Peter Pumpkin Eater to Humpty Dumpty
实时预览:http://plnkr.co/edit/uArV1FbZW7ONRzv5DN8f?p=preview