我有一个生成表行的dom-repeat
模板,其中一个行单元格包含一个按钮,当行值具有特定值时,我希望禁用该按钮。所以我的组件有这个代码,它使用一个计算绑定来设置按钮的disabled
属性的值:
<template is="dom-repeat" items="{{list}}" as="ticket">
<tr class$="{{ticket.status}}">
<td class="actions">
<paper-icon-button icon="add" on-tap="incTickets"
disabled="{{noAvailableTickets(ticket)}}">
</paper-icon-button>
</td>
<td>[[ticket.amount]]</td>
<td>[[ticket.event.title]]</td>
</tr>
</template>
在我的代码中我有这个方法:
noAvailableTickets : function(ticket) {
return ticket.event.available_tickets <= 0;
}
我可以看到,首次创建列表时会调用计算出的绑定方法,每个项目都会调用一次。
然后当我更新项目时,如下:
this.set('list.' + ind + '.amount', newamount);
不会重新计算计算出的绑定,并且不会再次调用该方法,即使我可以看到模板中ticket.amount
显示中的值实际发生了变化。
Polymer Data Binding entry in the developer's guide有关计算绑定的说法:
[...]属性绑定到
的声明参数computeFullName
的返回值,每当第一次或最后一次更改时都会重新计算。 {first
和last
是computeFullName
]
因此,假设计算出的绑定不知道对象值,其amount
属性与其他逻辑如何使用它来更新available_tickets
属性之间的相关性,我认为尝试使用完整更新的对象添加notifyPath
命令,如下所示:
this.notifyPath('list.' + displayId, ticket);
但这似乎没有任何效果。我错过了什么?
答案 0 :(得分:2)
我怀疑notifyPath
由于its dirty check而未在您的案例中触发更新。也就是说,list[0]
和ticket
引用相同的实例(尽管实例的属性已更改),因此它不被视为&#34;脏&#34 ;
我的jsbin实验证明,将list[0]
设置为修改后的克隆确实会触发更新。
attached: function() {
setTimeout(function() {
var copy = this.list[0].clone();
copy.amount = 'FREE';
this.set('list.0', copy);
}.bind(this), 1000);
}
但这可能不是实现这一目标的最佳方式。
根据Polymer docs,要在ticket
子属性发生更改时触发计算绑定,您可以在绑定中使用ticket.*
:
<paper-icon-button disabled="{{noAvailableTickets(ticket.*)}}">
Polymer({
...
noAvailableTickets: function(change) {
var ticket = change.base;
return ticket.event.available_tickets <= 0;
}
});
这里是jsbin。