我有一个<paper-progress>
栏,我想用它来显示时间的流逝。要更新条形图的值,我使用名为setInterval
的循环方法来更新dom-module
的属性。当我记录属性的值时,我看到正在正确添加值,但不幸的是我的进度条没有移动。就好像属性的更改没有被条形属性上的数据绑定集捕获。下面是一个大大减少的代码来举例说明它。
<dom-module id="x-test">
<template>
<paper-progress
value="{{progresso.value}}"
min="{{progresso.min}}"
max="{{progresso.max}}"
class="transiting">
</paper-progress>
</template>
<script>
Polymer({
is: 'x-test',
properties: {
progresso: {
type: Object,
value: {
min: 0,
max: 10000,
value: 0
}
}
},
attached: function(){
var timer = setInterval(this.count,1000);
},
count: function(){
var progresso = document.querySelector('test').progresso;
try {
if (progresso.value < progresso.max) {
progresso.value = progresso.value + 100;
} else {
progresso.value = progresso.max;
}
} catch (e) {
console.log(e.name + ": " + e.message);
}
}
});
</script>
</dom-module>
我错过了什么?为了让<paper-progress>
元素看到progresso
dom-module
属性中的更改,我该怎么办?两个元素都在同一个模块中。
P.S。:
clearInterval()
;但它包含在代码中。编辑:我在复制和粘贴代码时犯了一些错误。我修改了上面的代码以反映真实的代码。还添加了一些评论,以使我的情况更加清晰。
答案 0 :(得分:4)
当您拥有data binding to a subproperty时,设置子属性直接赢得不会自动更新数据绑定。您必须手动拨打this.notifyPath(SUBPROPERTY_PATH)
:
this.progresso.value = 20;
this.notifyPath('progresso.value');
...或使用this.set(SUBPROPERTY_PATH, VALUE)
。
this.set('progresso.value', 20);
您好像正在尝试定义名为test
的自定义元素,但是Web组件规范requires the element name be hyphenated,因此名称应该类似于x-test
:
<dom-module id="x-test">
<template>...</template>
<script>
Polymer({
is: 'x-test',
...
});
</script>
</dom-module>
要在Polymer对象上声明方法,请指定所需的方法名称,后跟冒号,然后指定函数表达式:
Polynmer({
// this.count: function() { // DON'T DO THIS
count: function() {
...
}
});
请注意document.querySelector()
查询整个文档而不是Polymer元素。查询文档可能会有问题,因为您可能在文档中有多个元素实例(如果您在特定元素之后需要将类或ID应用于元素以供选择),并且document.querySelector()
不能查询元素的影子DOM。
从Polymer方法中,您应该使用this.$$(SELECTOR)
(或Polymer.dom(this.root).querySelector(SELECTOR)
),它适用于Shady DOM(在Polymer 1中默认)或Shadow DOM(在Polymer 2中默认)。
var myEl = this.$$('a-class-in-my-element');
注意:事实证明您根本不需要查询元素(请参阅访问元素属性)。
由于progresso
是您的Polymer对象的属性,您可以从Polymer方法直接从this
(例如this.progresso
)访问它,因此count()
应该看起来像这样:
count: function() {
// var progresso = document.querySelector('test').progresso; // DON'T DO THIS
var progresso = this.progresso;
...
}
Object
属性要初始化Object
属性的值,请务必use a function that returns the intial value。否则,元素的所有实例将共享相同的Object
,这可能会导致无意的副作用。
Polymer({
...
properties: {
progresso: {
type: Object,
value: function() {
return {min: 0, max: 10000, value: 0};
}
}
}
});
请注意,您需要绑定setInterval
回调的上下文,以便它引用您的Polymer对象(以便您的回调&#39; this
引用Polymer对象而不是外部对象context,通常是Window
对象。)
attached: function() {
setInterval(this.count.bind(this), 1000);
}
假设你可以分离你的元素,你应该在detached
中添加清理来停止在attached
中启动的间隔计时器:
attached: function() {
this._timerId = setInterval(...);
},
detached: function() {
clearInterval(this._timerId);
}
HTMLImports.whenReady(() => {
Polymer({
is: 'x-test',
properties: {
progresso: {
type: Object,
value: () => ({
min: 0,
max: 10000,
value: 0
})
}
},
attached: function() {
this._timerId = setInterval(this.count.bind(this), 1000);
},
detached: function() {
clearInterval(this._timerId);
},
count: function() {
const progresso = this.progresso;
if (progresso.value < progresso.max) {
this.set('progresso.value', progresso.value + 100);
console.log('value', progresso.value);
} else {
this.set('progresso.value', progresso.max);
clearInterval(this._timerId);
}
}
});
});
&#13;
<head>
<base href="https://polygit.org/polymer+1.9.3/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-progress/paper-progress.html">
</head>
<body>
<x-test></x-test>
<dom-module id="x-test">
<template>
<style>
paper-progress {
--paper-progress-height: 20px;
width: 100%;
}
</style>
<paper-progress
value="{{progresso.value}}"
min="{{progresso.min}}"
max="{{progresso.max}}"
class="transiting">
</paper-progress>
</template>
</dom-module>
</body>
&#13;