我有一个具有多个属性的Polymer.dart元素,例如
<code-mirror lines="{{lines}}" widgets="{{widgets}}">
</code-mirror>
在某些情况下lines
和widgets
同时更改,有时只会widgets
更改。
我想在相同的事件循环回合中独立地重新呈现组件一次。
是否有一种良好的内置方式来实现这一目标?
此处的其他问题是widgets
的解释取决于lines
的内容以及linesChanged
和widgetsChanged
回调到达的顺序取决于浏览器,例如在widgetsChanged
之前,Firefox linesChanged
首先到达,如果我在linesChanged
回调中进行任何状态管理,则组件进入不一致状态。
现在我使用这样的辅助类:
class Task {
final _callback;
var _task;
Task(this._callback);
schedule() {
if (_task == null) {
_task = new async.Timer(const Duration(milliseconds: 50), () {
_task = null;
_callback();
});
}
}
}
final renderTask = new Task(this._render);
linesChanged() => renderTask.schedule();
widgetsChanged() => renderTask.schedule();
但这看起来很破碎。也许我的Polymer元素架构不正确(即widgets
有两个属性,具体取决于lines
)?
答案 0 :(得分:1)
*Changed
方法绝对是解决问题的正确方法。但是,您正试图在异步传送系统中强制同步。通常,我们鼓励人们观察属性变化并对其做出反应,而不是依赖于按特定顺序调用的方法。
您可以使用的一件事是observe
块。这样,您就可以为这两个属性定义一个回调并做出相应的反应:
http://www.polymer-project.org/docs/polymer/polymer.html#observeblock
Polymer的数据绑定系统在重新渲染DOM方面做的工作量最少。通过添加Object.observe()
,它甚至更快。我必须更多地了解你的元素,以了解需要渲染的内容,但你可能会创建一个过早的优化。
答案 1 :(得分:1)
我认为有三种可能的解决方案: 请参阅:http://jsbin.com/nilim/3/edit
isRender
)。添加ChangeWatcher
(即isRenderChanged()
,您可以在其中调用昂贵的渲染方法)autoUpdate
或true
的标记(即false
)。当autoUpdate
= false
时,您必须手动调用render
方法。如果设置为true
,则会自动调用render()
。 解决方案1的缺点是您只能对所有观察到的属性执行一种行为。在调用render之前设置特定属性(即大小)时,有时需要执行不同的操作。解决方案1无法做到这一点。
答案 2 :(得分:0)
我认为没有更好的方法。你可以省略50ms的延迟(只是Timer.run(() {...});
),因为工作安排在正在进行的房产变更之后(不过我的经验,不是100%肯定)