每多个属性更改一次渲染Polymer元素

时间:2014-02-01 20:04:32

标签: dart dart-polymer

我有一个具有多个属性的Polymer.dart元素,例如

<code-mirror lines="{{lines}}" widgets="{{widgets}}">
</code-mirror>

在某些情况下lineswidgets同时更改,有时只会widgets更改。

我想在相同的事件循环回合中独立地重新呈现组件一次。

是否有一种良好的内置方式来实现这一目标?

此处的其他问题是widgets的解释取决于lines的内容以及linesChangedwidgetsChanged回调到达的顺序取决于浏览器,例如在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)?

3 个答案:

答案 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

  1. 对多个属性使用带有一个回调的观察块(回调只会被调用一次)
  2. 创建由其他两个属性(线条和小部件)设置的其他属性(即isRender)。添加ChangeWatcher(即isRenderChanged(),您可以在其中调用昂贵的渲染方法)
  3. 指定可设置为autoUpdatetrue的标记(即false)。当autoUpdate = false时,您必须手动调用render方法。如果设置为true,则会自动调用render()
  4. 解决方案1的缺点是您只能对所有观察到的属性执行一种行为。在调用render之前设置特定属性(即大小)时,有时需要执行不同的操作。解决方案1无法做到这一点。

答案 2 :(得分:0)

我认为没有更好的方法。你可以省略50ms的延迟(只是Timer.run(() {...});),因为工作安排在正在进行的房产变更之后(不过我的经验,不是100%肯定)