【问题标题】:Polymer v1.0 - Data Binding changes not propagatingPolymer v1.0 - 数据绑定更改未传播
【发布时间】:2015-08-20 06:32:19
【问题描述】:

尝试使用 Polymer v1.0,目前正在加载 2 个数据集。第一组将设置视图并重复我的自定义元素。第二组是异步加载的,加载后它将尝试通过 routeid 进行匹配(如果可用)。在匹配时,它会将自己作为对象插入到第一个对象中。

当我这样做时,视图不会更新,但如果我执行 console.log 并跟踪它,数据就在那里。

我发现如果我要清除第一个对象,使用 async 并稍后将其设置回来,视图会更新,但这会导致我的显示有一段时间是空白的。 如何强制它使用更新的内容重绘?

第一个设置项目的视图。

[ 
        {
            "anchors":[ 
                {"anchorid":1, 
                 "routes":[ 
                     {"name":"route 1", "routeid":1 },
                     {"name":"route 2", "routeid":2 },
                     {"name":"route 3", "routeid":3 }  
                 ] 
                },
                {"anchorid":2, 
                 "routes":[ 
                     {"name":"route 4", "routeid":4 },
                     {"name":"route 5", "routeid":5 },
                     {"name":"route 6", "routeid":6 }  
                 ] 
                }
            ]
        },
        {
            "anchors":[ 
                {"anchorid":3, 
                 "routes":[ 
                     {"name":"route 7", "routeid":7 },
                     {"name":"route 8", "routeid":8 },
                     {"name":"route 9", "routeid":9 }  
                 ] 
                },
                {"anchorid":4, 
                 "routes":[ 
                     {"name":"route 10", "routeid":10 },
                     {"name":"route 11", "routeid":11 },
                     {"name":"route 12", "routeid":12 }  
                 ] 
                }
            ]
        }
    ]

第二个数据集

 [
  {"routeid":3, "status":2},
  {"routeid":5, "status":3},
  {"routeid":1, "status":1}
 ]

我的元素代码

    <dom-module id="anchor-listdebug">
    <template>
        <h1>Anchor list</h1>
        <template is="dom-repeat" items="{{data}}">
            <h2>Anchor Group </h2>
            <template is="dom-repeat" items="{{item.anchors}}" as="anchordata">
                <anchor-item anchor="{{anchordata}}"></anchor-item>

            </template>
        </template>
    </template>

    <script>
        Polymer ({
            is:"anchor-listdebug",
            ready : function () {
                //data is loaded here via iron-ajax
                this.data = data;
                //data2 is loaded on data response
                this.data2 = data2;

                // emulate 2nd set of data loading, if this.processData is called immediately, content updates fine.
                this.async (this.processData, 1000);
            },
            processData: function () {
                this.data.forEach (function (element) {
                    element.anchors.forEach (function (anchorElement){
                        anchorElement.routes.forEach (function (routeElement){
                            var myID = routeElement.routeid;
                            var data = this.data2.filter(function (record){
                                return record.routeid == myID;
                            });
                            if (data.length >0) {
                                data = data[0];
                                routeElement.data = data;
                            }
                        }); 
                    });
                });
            }
        });
    </script>
</dom-module>

<dom-module id="anchor-item">
    <template>
        <h2>Anchor ID: {{anchor.anchorid}} </h2>
        <template is="dom-repeat" items="{{anchor.routes}}" as="routedata">

            <route-item route="{{routedata}}"></route-item>
        </template>

    </template>

    <script>
        Polymer ({
            is:"anchor-item",
            properties: {
                anchor:{ type:Object, notify:true}
            }

        });
    </script>
</dom-module>

<dom-module id="route-item">
    <template>
        <h3>Route id: <span>{{route.routeid}}</span></h3>
        <h3>Route name: <span>{{route.name}}</span></h3>
        <h3>Route status: <span>{{route.data.status}}</span></h3>

    </template>

    <script>
        Polymer ({
            is:"route-item",
            properties: {
                route:{ type:Object, notify:true}
            }

        });
    </script>
</dom-module>

【问题讨论】:

  • 我找到了一个解决方案。创建一个新对象来临时存储数据。设置数据 = {};对临时对象进行对象操作;创建另一个最小延迟为 1 的异步函数然后设置 data = temp 对象。然后,我的显示视图将使用新内容进行更新。有没有更好的方法来做到这一点?

标签: javascript polymer polymer-1.0 2-way-object-databinding


【解决方案1】:

确保您使用 set API 来操作您的对象 (docs)。而不是this.data.anchors = someValue 使用this.set("data.anchors", someValue)

【讨论】:

    【解决方案2】:

    首先,您需要使用this.set("data.anchors", someValue),如前所述。您还需要更改模板绑定,否则生成的通知将被忽略。除了使用anchor="{{anchordata}}",您必须使用anchor="{{anchordata.*}}" 来监听所有记录更改,或者如果您希望更改仅响应数据中的一个特定键,则使用anchor="{{anchordata.SPECIFIC_KEY}}"

    【讨论】:

    • 我不确定我在哪里做这个。我正在更改的数据位于另一个对象内的数组内的数组内的对象中。数组 -> 对象 -> 数组 -> 对象 -> 数组 -> 对象 -> 在此处添加新对象
    • 我是否执行 set() 函数,其中我的“routeElement.data = data;”线是?但我的路是什么?会是“data[index].anchors.routes[2ndindex].newdata”吗?
    • 您应该从一个简单的模板重复开始,直到您掌握它。考虑以下示例,对于数组属性data。这提醒了我,您还没有将您的 data 声明为属性。无论如何,对于该数组,如果您想设置索引为 5 的项目,您将执行以下操作:this.set("data.5", item)。从那里,你可以更深入。如果该项目是一个对象,您可以使用以下设置该对象的特定键:this.set("data.5.someKey", someValue) 等等。
    • 一般来说,您绝对应该阅读有关绑定的文档,尤其是结构化数据:polymer-project.org/1.0/docs/devguide/…
    • 太棒了。最初,当我阅读文档时,我不知何故看多了。我只读到它不支持数组,并且我认为还有其他方法可以做到这一点。我意识到的另一个问题是我不能在 forEach 循环中使用“this.set”,因为它的范围不同。谢谢!
    【解决方案3】:

    更新了我的 forEach 循环以包含用于构造用于 set() 函数的路径的索引。

    <script>
            Polymer ({
                is:"anchor-listdebug",
                ready : function () {
                    //data is loaded here via iron-ajax
                    this.data = data;
                    //data2 is loaded on data response
                    this.data2 = data2;
    
                    this.async (this.processData, 1000);
                    //this.processData();
                },
                processData: function () {
                    var scope = this;
                    this.data.forEach (function (element, index1) {
                        element.anchors.forEach (function (anchorElement, index2){
                            anchorElement.routes.forEach (function (routeElement, index3){
                                var myID = routeElement.routeid;
                                var data = this.data2.filter(function (record){
                                    return record.routeid == myID;
                                });
                                if (data.length >0) {
                                    data = data[0];
                                    var tpath = "data."+index1+".anchors."+index2+".routes."+index3+".data";
                                    scope.set(tpath, data);
                                }
                            }); 
                        });
                    });
                }
            });
        </script>
    

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      相关资源
      最近更新 更多