重置可观察的表单字段Knockout

时间:2016-08-23 11:47:46

标签: javascript asp.net-mvc knockout.js

在我的MVC项目中,我有一个包含3个表单的视图和一个KO ViewModel

在每张表格上,我都有一个重置按钮来清除自己的字段。

我无法使用input type="reset",因为它不会更新可观察的值。

我无法重置View Model,因为这会重置{strong>所有 View Model的观察点,我只需要重置那些触发重置的表单

我可以编写3个函数,每个表单一个,并手动删除每个表单字段,如下所示:

this.onForm1Reset = function () {
    this.field1('');
    this.field2('');
    //etc..
}

this.onForm2Reset = function () {
    this.field3('');
    this.field4('');
    //etc..
}

this.onForm3Reset = function () {
    this.field5('');
    this.field6('');
    //etc..
}

但我正在寻找更全面,更短的解决方案。

我在网上做了很多研究,但找不到一个好的解决方案。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:3)

如果您可以对表单的字段进行分组,则可以在每个表单上使用with绑定为表单成员提供不同的context,因此reset函数(作为附加到重置按钮的click处理程序只会查看其自身形式的observable。

如果你不能对字段进行分组,那么(不太优选)的可能性是运行包含重置按钮的表单的绑定元素,重置它们的值,并为它们触发更改事件。我的代码段中的注释掉的代码会这样做。

vm = {
    fieldset1: {
      field0: ko.observable(),
      field1: ko.observable()
    },
    fieldset2: {
      field2: ko.observable(),
      field3: ko.observable()
    },
    fieldset3: {
      field4: ko.observable(),
      field5: ko.observable()
    },
    reset: function(data) {
      for (var key in data) {
        if (data.hasOwnProperty(key)) {
          data[key]('');
        }
      }
    };

    ko.applyBindings(vm);

    /*
    $('body').on('click', '[type="reset"]', function() {
      $(this.parentNode).find('[data-bind*="value:"]').each((index, item) => {
        $(item).val('').change();
      });
    });
    */
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<form data-bind="with: fieldset1">
  <input data-bind="value:field0" />
  <input data-bind="value:field1" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>

<form data-bind="with: fieldset2">
  <input data-bind="value:field2" />
  <input data-bind="value:field3" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>

<form data-bind="with: fieldset3">
  <input data-bind="value:field4" />
  <input data-bind="value:field5" />
  <input type="reset" data-bind="click: $parent.reset" />
</form>

答案 1 :(得分:1)

更实际的解决方案是将视图模型包含在observable中,并在重置时重新创建模型:

function MyViewModel()
{
    this.field1 = ko.observable();
    this.field2 = ko.observable();

    // etc...
}

var model = {
    data: ko.observable(new MyViewModel()),
    reset: function() {
        model.data(new MyViewModel());
    }
};

ko.applyBindings(model);

在你的HTML中:

<body data-bind="with: data">
    ...
    <button data-bind="click: $root.reset">Reset</button>
</body>

请参阅Fiddle

更新(根据您的评论):

由于您不想替换整个视图模型但只重置某些字段,我假设您必须向模型中引入reset()方法:

function MyViewModel()
{
    this.field1 = ko.observable();
    this.field2 = ko.observable();

    this.reset = function() {
        this.field1('');
        this.field2('');
    }.bind(this);
}

ko.applyBindings(new MyViewModel());

在你的HTML中:

<button data-bind="click: reset">Reset</button>

答案 2 :(得分:1)

您可能还需要考虑将ViewModel拆分为每个表单(字段组)一个单独的VM 使用此方法,您可以通过重新创建相应的ViewModel来重置表单。

答案 3 :(得分:0)

这样的事情会起作用吗?你有什么功能来清空可观察的东西?取决于点击重置?

this.emptyObservablesRestForm1 = function () {
   this.field1(false);
}


this.emptyObservablesRestForm2 = function () {
       this.field2(false);
    }