重新设置Polymer 2.x中的表单 [英] Resetting forms in Polymer 2.x
问题描述
我正尝试重置我的表单。我究竟做错了什么?什么是最佳实践?
我演示的问题在于 connectedCallback()
持续地(不只是在初始加载时),从而在每次更新时将 savedItem
的值更新为 newItem
。
https://plnkr.co/edit/wRdXXws2UXl3VXrycqua?p=preview
my-demo.html
< base href =https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/>
< link rel =importhref =polymer / polymer-element.html>
< link rel =importhref =paper-toggle-button / paper-toggle-button.html>
< dom-module id =my-demo>
< template>
< style>
:主机> * {
margin-top:40px;
font-size:18px;
}
button.save {
color:white;
background-color:blue;
}
< / style>
< / paper-toggle-button checked ={{item.alice}}> Alice< / paper-toggle-button>
< / paper-toggle-button checked ={{item.bob}}> Bob< / paper-toggle-button>
< / paper-toggle-button checked ={{item.charlie}}> Charlie< / paper-toggle-button>
< paper-toggle-button checked ={{item.dave}}> Dave< / paper-toggle-button>
<按钮>重置< /按钮>
< button class =saveon-tap =_ reset>储存< /按钮>
< / template>
< script>
class MyDemo extends Polymer.Element {
static get is(){
return'my-demo';
}
静态获取属性(){
return {
item:{
type:Object,
notify:true,
value: ()=> {
return {
alice:false,
bob:false,
charlie:false,
dave:true,
};
},
},
savedItem:{
type:Object,
notify:true,
},
};
}
connectedCallback(){
super.connectedCallback();
this.set('savedItem',this.item);
static get observers(){
return [
'_itemChanged(item。*)',
];
}
_itemChanged(newItem){
console.log('saved-item',this.savedItem);
console.log('new-item',newItem);
}
_reset(){
this.set('item',this.savedItem);
}
}
window.customElements.define(MyDemo.is,MyDemo);
< / script>
< / dom-module>
编辑
重新创建问题的步骤
-
打开您的控制台。 p>在Plunker中导航到my-demo.html
-
点击其中一个切换开关。
-
注意在控制台中,
注意,这似乎是以下代码块的结果。savedItem
属性更新到当前的项目
属性。connectedCallback(){
super.connectedCallback();
this.set('savedItem',this.item);
}
是?因为我认为 connectedCallback()
只会在初始化时触发一次?
tldr; 在这种情况下, connectedCallback()
实际上不会被多次调用。 savedItem
和 item
在您的代码中始终是相同的对象,因为JavaScript会传递对象参考资料。
对象引用
以下内容:
connectedCallback(){
this.set('savedItem',this.item);
}
_reset(){
this.set('item',this.savedItem);
savedItem
和 item
都是对同一个对象的引用。调用 this.set()
不会自动克隆操作数(也不会自动克隆 =
运算符)。
一种解决方案是在赋值前克隆对象(使用 ES2017对象扩散运算符):
connectedCallback() {
this.savedItem = {... this.item};
}
_reset(){
this.item = {... this.savedItem};
}
更新的plunker b
$ b 方法)
重置表单的一个简单方法是让 iron-form
处理表单的 reset
事件,它将窗体的命名输入重置为它们的初始值。这样可以避免您不必声明 savedItem
,也无需额外的JavaScript来管理它。为了达到这个目的,在< iron-form>
中<< code>< paper-toggle-button> ,并添加 name
属性。然后,在表单中插入一个< input type =reset>
,作为重置按钮。
<铁形式>
< form>
< input type =resetclass =save>
< / form>
< / iron-form>
I am trying to reset my form. What am I doing wrong? What is best-practice?
My problem on the demo is that connectedCallback()
appears to fire continually (not just on initial load), thereby losing the value of savedItem
by updating it to newItem
on each update.
Here is the same issue on Github.
https://plnkr.co/edit/wRdXXws2UXl3VXrycqua?p=preview
my-demo.html<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<link rel="import" href="polymer/polymer-element.html">
<link rel="import" href="paper-toggle-button/paper-toggle-button.html">
<dom-module id="my-demo">
<template>
<style>
:host > * {
margin-top: 40px;
font-size: 18px;
}
button.save {
color: white;
background-color: blue;
}
</style>
<paper-toggle-button checked="{{item.alice}}">Alice</paper-toggle-button>
<paper-toggle-button checked="{{item.bob}}">Bob</paper-toggle-button>
<paper-toggle-button checked="{{item.charlie}}">Charlie</paper-toggle-button>
<paper-toggle-button checked="{{item.dave}}">Dave</paper-toggle-button>
<button>Reset</button>
<button class="save" on-tap="_reset">Save</button>
</template>
<script>
class MyDemo extends Polymer.Element {
static get is() {
return 'my-demo';
}
static get properties() {
return {
item: {
type: Object,
notify: true,
value: () => {
return {
alice: false,
bob: false,
charlie: false,
dave: true,
};
},
},
savedItem: {
type: Object,
notify: true,
},
};
}
connectedCallback() {
super.connectedCallback();
this.set('savedItem', this.item);
}
static get observers() {
return [
'_itemChanged(item.*)',
];
}
_itemChanged(newItem) {
console.log('saved-item', this.savedItem);
console.log('new-item', newItem);
}
_reset() {
this.set('item', this.savedItem);
}
}
window.customElements.define(MyDemo.is, MyDemo);
</script>
</dom-module>
Edit
Steps to recreate the problem
Open your console.
Navigate in the Plunker to my-demo.html
Click one of the toggle switches.
Notice in the console, the
savedItem
property updates to the currentitem
property.Notice, this appears to be the result of the following code block.
connectedCallback() { super.connectedCallback(); this.set('savedItem', this.item); }
But how can this be? Because I thought connectedCallback()
only fired once at initialization time?
tldr; The connectedCallback()
isn't actually being called more than once in this case. savedItem
and item
are always the same object in your code because JavaScript passes objects by reference.
Object references
In the following:
connectedCallback() {
this.set('savedItem', this.item);
}
_reset() {
this.set('item', this.savedItem);
}
savedItem
and item
are both references to the same object. Calling this.set()
does not automatically clone the operand (nor does the =
operator).
One solution is to clone the object before assignment (using ES2017 object-spread operator):
connectedCallback() {
this.savedItem = {...this.item};
}
_reset() {
this.item = {...this.savedItem};
}
Best practice (or simpler reset method)
A simpler way to reset the form is to let iron-form
handle the form's reset
event, where it resets the form's named inputs to their initial values. This saves you from having to declare savedItem
and no extra JavaScript to manage it.
To accomplish this, wrap the <paper-toggle-button>
's in an <iron-form>
, and add name
attributes to them. Then, insert an <input type="reset">
in the form, which serves as the reset button.
<iron-form>
<form>
<paper-toggle-button name="alice" checked="{{item.alice}}">Alice</paper-toggle-button>
<paper-toggle-button name="bob" checked="{{item.bob}}">Bob</paper-toggle-button>
<paper-toggle-button name="charlie" checked="{{item.charlie}}">Charlie</paper-toggle-button>
<paper-toggle-button name="dave" checked="{{item.dave}}">Dave</paper-toggle-button>
<input type="reset" class="save">
</form>
</iron-form>
这篇关于重新设置Polymer 2.x中的表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!