重新设置Polymer 2.x中的表单 [英] Resetting forms in Polymer 2.x

查看:152
本文介绍了重新设置Polymer 2.x中的表单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正尝试重置我的表单。我究竟做错了什么?什么是最佳实践?



这里是我的Plunk演示。



我演示的问题在于 connectedCallback()持续地(不只是在初始加载时),从而在每次更新时将 savedItem 的值更新为 newItem



这是同一个问题在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 =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>



编辑



重新创建问题的步骤


  1. 在这里打开演示。


  2. 打开您的控制台。 p>在Plunker中导航到my-demo.html

  3. 点击其中一个切换开关。


  4. 注意在控制台中, 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>



demo


I am trying to reset my form. What am I doing wrong? What is best-practice?

Here is my Plunk demo.

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

  1. Open the demo here.

  2. Open your console.

  3. Navigate in the Plunker to my-demo.html

  4. Click one of the toggle switches.

  5. Notice in the console, the savedItem property updates to the current item property.

  6. 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};
}

updated plunker


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>

demo

这篇关于重新设置Polymer 2.x中的表单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆