该方案在某些条件下阻止了价值的变化。为此,我发现 observer 函数本身是检查更改的最佳位置。
但是,在观察者中更改属性的值会导致观察者再次变成黑洞。
properties: {
foobar: {
type: String,
observer: 'foobarChanged'
}
},
foobarChanged: function(oldValue, newValue) {
if(!matchesCertainCondition(newValue))
this.foobar = oldValue;
}
但是,我无法提出直接的解决方案。在Polymer 1.x中有没有办法做到这一点?
为什么他们应该在观察者本身内向观察值发射变化事件?
也欢迎变通办法!
答案 0 :(得分:1)
可以使用基于另一个公共属性的computed property
来解决此问题,而不是使用观察者。计算属性将检测对公共属性的所有更改,验证输入值,并可选地返回不同的值。
在此示例中,计算属性_index
计算基于index
的值,最大值为100
。
// template
<div>[[_index]]</div>
// script
Polymer({
is: 'x-foo',
properties: {
index: Number,
_index: {
computed: '_computeIndex(index)'
}
},
_computeIndex: function(index) {
return Math.min(index, 100);
}
);
HTMLImports.whenReady(() => {
Polymer({
is: 'x-foo',
properties: {
index: Number,
_index: {
computed: '_computeIndex(index)'
}
},
_computeIndex: function(index) {
return Math.min(index, 100);
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo index="200"></x-foo>
<dom-module id="x-foo">
<template>
<div>index: [[index]]</div>
<div>_index: [[_index]]</div>
</template>
</dom-module>
</body>
答案 1 :(得分:1)
如果你需要它来处理双向数据绑定,我想出了一个(相当粗略的)解决方法。只需将您的属性设为一个对象,使用一个布尔键值表示切换或标记,告诉您它是否被内部或外部事件更改。这类似于其他回答者的评论,但是是异步安全的。 这看起来如下所示:
properties: {
foobar: {
type: Object,
notify: true,
value: {
value: 'blah',
internalToggle: false
},
observer: '_foobarChanged'
}
}
...
_foobarChanged: function(oldfoobar, newfoobar) {
if (oldfoobar.internalToggle != newfoobar.internalToggle) {
return
}
if (oldfoobar.value != newfoobar.value) {
// Do stuff
if(!matchesCertainCondition(newfoobar.value))
this.foobar = {value: oldfoobar.value,
internalToggle: !oldfoobar.internalToggle};
}
}
}
总是如此地狱,但它确实有效。老实说,在这一点上,几乎值得放弃聚合物的双向绑定,只是分裂成多个属性。