聚合物单模板实例不更新

Polymer Single template instances not updating

好像用single template through at least 2 layers of getters, the binding doesn't update anymore when the underlying value changes. Paradoxically this seems to work when using iterative templates代替。

有点难以解释,我不是 100% 确定这就是绑定失败的原因,所以这里有一个最小的(大概)示例来说明:

<polymer-element name="test-binding">
<template>
  <template bind="{{ getterMap }}">
    <span>{{ name }}</span>
  </template>
</template>
<script>
    (function(){
        Polymer('test-binding', {
            ready: function(){
                var getterMap = {};
                Object.defineProperty(this, 'getterMap', {
                    get: function(){ return getterMap; },
                    set: function(newValue){ getterMap = newValue; }
                });

                var name = 'foo';
                Object.defineProperty(getterMap, 'name', {
                    get: function(){ return name; },
                    set: function(newValue){ name = newValue; }
                });

                setInterval(function(){
                    this.getterMap.name = 'foo '+Math.random();
                }.bind(this), 2000);
            }
        });
    })();
</script>
</polymer-element>

以及随之而来的jsfiddle

稍作调整后,发现普通模板绑定无法直接在对象上使用 Object.defineProperty。您的列表模板之所以有效,是因为它将 getterMap 粘贴在未由 Object.defineProperty 定义的 属性 上的数组中。将列表转换为 Object.defineProperty 后,它停止工作。

更新:

经进一步测试,仅适用于get()s和set()s。如果 defineProperty 是用 writable value 描述符描述的,它工作得很好。

经过一些搜索后,Google 组上的 post 表明如果您想使用数据绑定,可能无法使用 getters/setters。

Attributes and Observers vs Getters/Setters

更新二:

根据this issue discussion, you may add data-binding to object accessors, via Object.observe(). It requires the use of Object.getNotifier() and Notifier.notify(). However, use of this API comes with some concerns. To see it in use, check out this fiddle

  • Object.observe() API 是 ES Harmony 提案的一部分。因此,它高度依赖于浏览器。
  • 目前支持的浏览器只有Chrome.