Element: form resetFields并没有清空表单

Created on 20 Dec 2016  ·  20Comments  ·  Source: ElemeFE/element

按照文档的说法

resetFields 对整个表单进行重置,将所有字段值重置为空并移除校验结果

但是实际上resetFields是清空validateMessage,然后把值重置成了上一次初始化的值。

      resetField() {
        this.validateState = '';
        this.validateMessage = '';

        let model = this.form.model;
        let value = this.fieldValue;
        let path = this.prop;
        if (path.indexOf(':') !== -1) {
          path = path.replace(/:/, '.');
        }

        let prop = getPropByPath(model, path);

        if (Array.isArray(value) && value.length > 0) {
          this.validateDisabled = true;
          prop.o[prop.k] = [];
        } else if (value) {
          this.validateDisabled = true;
          prop.o[prop.k] = this.initialValue;
        }
      },

我的form在一个dialog里,这个表单会用于修改或者新建。
所以我需要在新建的时候去清空表单。而edit的时候又不能清空表单。
为了避免一次判断,我监听dialog的close事件,在close里调用form.resetField().
确发现并无法清空数据。

so 这是一个代码bug还文档bug?

repro

Most helpful comment

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

All 20 comments

你的form-item有prop属性么,需要这个属性

@baiyaaaaa 有的 如果我在open事件里做resetField,就清空。

提供一下demo把

@baiyaaaaa 恩 明天有空的话我做一个

@baiyaaaaa
http://jsfiddle.net/zpczjl/ohkLnk2o/1/

请查看,我设置了定时器。每2秒调用一下resetFiled。

  1. resetFiled没有清空form,已经是问题了。
  2. 可以改变一下form里的值,然后你会发现resetFiled执行后,form里的值被重置成了初始值,而非空。

对的,重置的含义就是重置为初始值,这跟浏览器表单的reset表现是一样的,你可以看看这个demo https://jsfiddle.net/WhiteCusp/9oyzhxjx/1/

@baiyaaaaa 所以文档写错了啊

resetFields 对整个表单进行重置,将所有字段值重置为并移除校验结果

我一开始就写了哎

so 这是一个代码bug还文档bug?

大兄弟啊!!!你没看完我写的东西啊,还让我重现。。。
pr!!pr!! https://github.com/ElemeFE/element/pull/1920

我也碰到这种情况了,然而我的解决方案是用父组件调用子组件的resetFiled方法,并且在赋值之前先reset,再赋值就ok了

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

@kelvshi 正解,感谢

你们是不是忘记在每个el-form-item的属性中加上prop了

@kelvshi 解决了非常感谢

也可以调用 setinitialValue 为空的

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

有具体代码吗?

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开对话框的时候给表单绑定的模型赋值了,这时候这个模型的初始值就变成了你所赋值的值,所以resetFields的时候,替换模型对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在数据里声明的初始值,解决方式是,等dialog已经初始化安装之后再给模型赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

有具体代码吗?

有的时候能解决,有的时候也无效

输入框添加属性 auto-complete="off"

我也碰到问题嘞

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开dialog的时候给表单绑定的model赋值了,这时候这个model的初始值就变成了你所赋值的值,所以resetFields的时候,会将model对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在data里声明的初始值,解决方式是,等dialog已经初始化mounted之后再给model赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

补充下,这个初始值指的是挂载的时候v-model指向的值,假如有用了v-if的换成v-show就好了

同一个问题,原来是因为我没用到prop属性.
解决:
直接重置data里的form{}
Object.keys(this.form).forEach(key => (this.form[key] = ''))

给下一个遇到这个问题的人,这个问题的本质是因为你编辑时,第一次打开对话框的时候给表单绑定的模型赋值了,这时候这个模型的初始值就变成了你所赋值的值,所以resetFields的时候,替换模型对应的每个值重置到初始值,这时候的初始值就是你编辑时赋值的那个值,而不是在数据里声明的初始值,解决方式是,等dialog已经初始化安装之后再给模型赋值,也就是
this.$nextTick(() => { // 这里开始赋值 this.model.xxx = xxx; })

有具体代码吗?

有的时候能解决,有的时候也无效

``

<el-button type="text" @click="getData">赋值数据</el-button>
<el-button type="text" @click="dialogFormVisible=true">打开 dialog</el-button>
<el-dialog title="收货地址" :visible.sync="dialogFormVisible">
  <el-form :model="form" ref="xxx">
    <el-form-item label="活动名称"  prop="name">
      <el-input v-model="form.name" autocomplete="off"></el-input>
    </el-form-item>
  </el-form>
  <div slot="footer" class="dialog-footer">
    <el-button @click="dialogFormVisible = false">取 消</el-button>
    <el-button type="primary" @click="xxx">确 定</el-button>
  </div>
</el-dialog>

  data() {
    return {
      dialogFormVisible: false,
      form: {
        name: '',
      },
    };
  },
  watch: {
    dialogFormVisible(val) {
      if (!val) {
        this.$refs.xxx.resetFields()
      }
    },
  },
  methods:{
    getData(){
      this.dialogFormVisible= true
      this.$nextTick(()=>{
        this.$set(this.form,'name','11111')
      })
    }
  }
Was this page helpful?
0 / 5 - 0 ratings