输入类型=重置和淘汰赛

时间:2013-04-08 21:38:58

标签: forms knockout.js

单击表单重置按钮时,Knockout不会更新observable。

http://jsfiddle.net/nQXeM/

HTML:

<form>
    <input type="text" data-bind="value: test" />
    <input type="reset" value="reset" />
</form>
<p data-bind="text: test"></p>

JS:

function ViewModel() {
    this.test = ko.observable("");
}

ko.applyBindings(new ViewModel());

显然,输入框的change事件没有被触发,就像这个jQuery测试一样: http://jsfiddle.net/LK8sM/4/

如果重置按钮没有触发更改事件,我们如何强制强制所有可以形成输入的observable更新而不必手动指定它们?

使用jQuery查找表单内的所有输入并触发更改事件会很容易,但我们假设我们只有一个基于敲门的控制形式。

2 个答案:

答案 0 :(得分:3)

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

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">

onFormReset将出现在您的视图模型中:

function ViewModel() {
    this.onFormReset = function () {
        //Your custom logic to notify or reset your specific fields.

        return true;
    }
}

在重置处理程序中,如果返回true,则JavaScript将继续在表单上调用其重置函数。但是,如果要设置绑定到值的observable,则不需要让JavaScript继续重置表单。因此,从技术上讲,您可以不返回任何内容,或者在该场景中返回false。

其他人可以进一步扩展这一点以自动通知表单中所有绑定的可观察对象,但这对我的目的有效。

答案 1 :(得分:1)

正如您所提到的,重置表单时不会触发change事件。如果您只使用KnockOut,我认为除非您创建可以注册reset事件并检测更改的自定义绑定,否则您确实没有其他选项 - 这仍然涉及手动JS,但至少它会集中。

更通用的方法虽然 需要jQuery,但是要创建一个函数来处理表单的reset事件,并检测当时表单输入的变化。

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

$('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();
            }
        }
    });
});

这是一个演示这个想法的小提琴:http://jsfiddle.net/Fm8rM/2/