gpt4 book ai didi

javascript - 我如何强制在 Polymer 中进行模板更新?

转载 作者:行者123 更新时间:2023-11-28 01:11:53 24 4
gpt4 key购买 nike

如何在 polymer 的 dom-repeat 模板中显示现有项目的变化?

我真的尝试了所有我能想到的,我可以在 polymer 文档或网络上找到。但没有任何效果。在下面,您会发现一个 html 页面,它使用一个小列表,并在您单击更改按钮时尝试将列表中的一个条目更改为另一个值。但是唯一会更改列表中更改按钮旁边的项目的是被注释掉的行。所有其他线路都尝试了,但失败了。

我知道重新渲染模板是一项耗时的任务,只有在必要时才应该进行,而 Polymer 会尽量避免这种情况。但为什么我(从他们世界之神的代码来看 ^^)不可能故意强制渲染?

创建一个完整的新对象,从列表中删除旧项目并插入新对象的方法(这就是注释行所做的)是一种解决方法,但当项目更复杂时,这确实是一项巨大的工作并具有甚至不显示的属性或数组。

我错过了什么?我没有尝试什么?如果有人能告诉我我可以做些什么来完成这样一个(从我的 Angular 来看)简单且非常常见的任务,我将非常高兴。

编辑(已解决):Tomasz Pluskiewicz 的解决方案部分成功。但我更新了代码以显示我当前的问题。项目的名称使用方法 format(...) 绑定(bind)。单击按钮时,该项目将从列表中删除。这很好用。但是如果您删除列表的最后一项,那么列表中新的最后一项的名称应该是“Last”。当名称直接绑定(bind)到属性名称时,这也有效。但如果我想对名称进行一些格式化(例如用 # 括起来),则不会更新此项目的显示。

EDIT2(部分解决):下一个不起作用的示例发生在为显示值而调用的方法中的值发生更改时。如果多次单击更改按钮,可以在示例中看到这一点。它增加了一个内部计数器,相应的文本将显示这个值。但这仅适用于计数器的第一次更改。随后的点击不会再次改变显示。显示屏显示第一次点击后计数器的值。但是,如果单击另一个更改按钮,则此按钮前面的文本会显示增加的计数器值。但也只有一次。它也不会显示后续点击的变化。 notifyPath 方法似乎检查值是否已更改,但没有考虑在用于显示值的方法内部,可能已更改某些内容以以另一种方式显示数据。

我在这个例子中包含了一个部分解决方案。如果被调用的方法有一个参数,当方法中的某些内容发生变化时该参数也会发生变化,那么将执行更新。这可以在与参数 displayEnforcer - format(item.name,displayEnforcer) 绑定(bind)的第二个变量中看到。每次更改计数器时,此变量都会设置为随机值。这会触发显示更新。

但这是一个非常奇怪的解决方案,没有必要。如果有人能更好地解决这个问题,那就太好了。

<link rel="import" href="components/bower_components/polymer/polymer.html">
<link rel="import" href="components/bower_components/paper-button/paper-button.html">
<dom-module id="polymer-test">
<template>
<table>
<template id="tpl" is="dom-repeat" items="{{list}}">
<tr>
<td>{{item.id}} - {{format(item.name)}}- {{format(item.name,displayEnforcer)}}</td>
<td><paper-button raised on-tap="tapDelete">delete</paper-button></td>
<td><paper-button raised on-tap="tapChange">change</paper-button></td>
</tr>
</template>
</table>
</template>
</dom-module>
<script>
Polymer(
{
is: "polymer-test",
properties:
{
count: {type: Number, value:0}
,list: {type: Array, value: [{id:0,name:"First"}
,{id:1,name:"Second"}
,{id:2,name:"Third"}
,{id:3,name:"Fourth"}
,{id:4,name:"Fifth"}
,{id:5,name:"Last"}
]}
,displayEnforcer: {type:Number,value:Math.random()}
},
format: function(name,dummy)
{
return "#" + name + " - " + this.count + "#";
},
tapChange: function(e)
{
this.count++;
this.displayEnforcer = Math.random();
this.notifyPath("list." + (e.model.index) + ".name","changed");
},
tapDelete: function(e)
{
if(this.list.length == 1)
return;
this.splice("list",e.model.index,1);
if(this.list.length > 0)
this.list[this.list.length-1].name = "Last";
this.notifyPath("list." + (this.list.length-1) + ".name",this.list[this.list.length-1].name);
}
});
</script>

最佳答案

您可以使用 notifyPath刷新单个列表元素属性的绑定(bind):

tapChange: function(e) {
this.notifyPath('list.' + e.model.index + '.name', 'changed');
}

参见:https://github.com/Polymer/polymer/issues/2068#issuecomment-120767748


这种方式不会重新渲染整个中继器,而只是更新必要的数据绑定(bind)节点。

编辑

你的 format函数没有得到更新,因为它不使用作为项目名称的通知路径。当您删除一个元素时,呈现的转发器中该元素的索引不会改变,即使实际项目发生变化也是如此。换句话说,当你删除第五个元素时,索引 4 仍然是 4。

作为解决方法,您可以添加 item.nameformat调用以便在您通知该路径时刷新它:

<td>{{item.id}} - {{format(index, item.name)}}</td>

您甚至不必在示例中使用该值。重新评估绑定(bind)就足够了。

关于javascript - 我如何强制在 Polymer 中进行模板更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37341743/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com