Forms 输入类型=重置和敲除

Forms 输入类型=重置和敲除,forms,knockout.js,Forms,Knockout.js,单击表单重置按钮时,敲除不会更新观察值 HTML: 很明显,没有触发输入框的更改事件,如jQuery测试所示: 如果重置按钮没有触发更改事件,我们如何强制所有绑定到表单输入的可观察对象更新,而不必手动指定它们 使用jQuery查找表单中的所有输入并触发更改事件非常简单,但我们假设我们有一个仅限敲除的受控表单。如您所述,表单重置时不会触发更改事件。如果您只使用KnockOut,我认为您实际上没有may选项,除非您创建可以注册reset事件并检测更改的自定义绑定-这仍然需要手动JS,但至少是集中

单击表单重置按钮时,敲除不会更新观察值

HTML:

很明显,没有触发输入框的更改事件,如jQuery测试所示:

如果重置按钮没有触发更改事件,我们如何强制所有绑定到表单输入的可观察对象更新,而不必手动指定它们


使用jQuery查找表单中的所有输入并触发更改事件非常简单,但我们假设我们有一个仅限敲除的受控表单。

如您所述,表单重置时不会触发
更改事件。如果您只使用KnockOut,我认为您实际上没有may选项,除非您创建可以注册
reset
事件并检测更改的自定义绑定-这仍然需要手动JS,但至少是集中化的

一种更通用的方法,尽管它确实需要jQuery,但它是创建一个函数来处理表单的
reset
事件,并检测当时表单输入上的更改

下面是一个可能有效的事件处理程序示例。请注意,这不是生产就绪代码。在使用之前,我会用一个好的jQuery眼睛查看它:)

这里有一把小提琴演示了这个想法:

我复制并修改了,以便为表单重置事件创建类似的绑定:

ko.bindingHandlers['reset'] = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (typeof valueAccessor() !== 'function')
            throw new Error('The value for a reset binding must be a function');

        ko.utils.registerEventHandler(element, 'reset', function (event) {
            var handlerReturnValue;
            var value = valueAccessor();

            try {
                handlerReturnValue = value.call(bindingContext['$data'], element);
            } finally {
                if (handlerReturnValue !== true) {
                    if (event.preventDefault)
                        event.preventDefault();
                    else
                        event.returnValue = false;
                }
            }
        });
    }
};
您可以将其绑定为:

<form data-bind="reset: onFormReset">
在重置处理程序中,如果返回true,则JavaScript将继续在表单上调用其重置函数。但是,如果您正在设置绑定到值的可观察对象,那么实际上不需要让JavaScript继续重置表单。因此,从技术上讲,您不能返回任何内容,或者在该场景中返回false


其他人可以进一步扩展此功能,以自动通知表单中的所有绑定观测值,但这对我来说是有效的。

您反对将重置作为viewmodel方法实现吗?正如您所指出的,这似乎是一个更大的问题,与
reset
s未触发更改有关,这可能是一个重要的问题。如果viewmodel中的一个方法可以重置所有观察值,而不必手动列出它们,那么它将起作用。但我只想重置仅绑定到输入的可观测值。
$('form').on('reset', function (evt) {
    evt.preventDefault();
    $(this).find('input, select, textarea').each(function () {
        if ($(this).is('input[type="radio"], input[type="checkbox"]')) {
            if ($(this).is(':checked') !== $(this)[0].defaultChecked) {
                $(this).val($(this)[0].defaultChecked);
                $(this).trigger('click');
                $(this).trigger('change');
            }
        } else {
            if ($(this).val() !== $(this)[0].defaultValue) {
                $(this).val($(this)[0].defaultValue);
                $(this).change();
            }
        }
    });
});
ko.bindingHandlers['reset'] = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        if (typeof valueAccessor() !== 'function')
            throw new Error('The value for a reset binding must be a function');

        ko.utils.registerEventHandler(element, 'reset', function (event) {
            var handlerReturnValue;
            var value = valueAccessor();

            try {
                handlerReturnValue = value.call(bindingContext['$data'], element);
            } finally {
                if (handlerReturnValue !== true) {
                    if (event.preventDefault)
                        event.preventDefault();
                    else
                        event.returnValue = false;
                }
            }
        });
    }
};
<form data-bind="reset: onFormReset">
function ViewModel() {
    this.onFormReset = function () {
        //Your custom logic to notify or reset your specific fields.

        return true;
    }
}