多次提交淘汰赛

Multiple submit in knockout

我们有一个submit binding in knockout,但是我们只能在整个表单上使用它,所以在多次提交的情况下 按钮,它们都触发相同的绑定。我想对每一个都采取不同的操作,但是我不知道如何区分哪个被点击,例如:

HTML:

<form data-bind="submit: save">
    <input type=submit name=save value=Save>
    <input type=submit name=saveAndClose value="Save & close">
</form>

虚拟机:

var ViewModel = function () {
    this.save = function (form) {
        var clicked = 'how to find out?';

        if (clicked === 'save') {
            // save
        } else if (clicked === 'saveAndClose') {
            // save
            // close
        }
    };
};

是的,我可以在每次提交时使用 click 绑定,但是没有可用的 form 元素,是的 - 我可以通过不同的方式获得它,但也许你知道更好的解决方案。

你呢?

好吧,您可以对每个输入使用点击绑定并传递一个 $element 变量作为参数。因此:

<form>
    <input type=submit name=save data-bind="click: save.bind(null, $element)" value=Save>
    <input type=submit name=saveAndClose data-bind="click: save.bind(null, $element)" value="Save & close">
</form>
在这种情况下,

bind in javascript 创建一个具有指定 this (null) 和参数 ($element) 的新函数。因此,很容易得到一个表单元素,并确定点击了哪个输入:

var ViewModel = function () {
    this.save = function (el) {
        var clicked = el.getAttribute('name');
        var form = el.parentElement;

            console.log(clicked, form)
        if (clicked === 'save') {
            // save
        } else if (clicked === 'saveAndClose') {
            // save
            // close
        }
    };
};

Working fiddle

但是请注意,此方法依赖于标记,如果输入不是表单元素的直接子元素,您可能需要找到另一种方法来获取表单元素本身而不是 parentElement

重载 submit 绑定以允许在任何元素上使用它。

JSFiddle:Knockout submit binding applicable onto any button (使用 jQuery)

绑定过载:

var overridden = ko.bindingHandlers.submit.init;
var $clickedButton;
ko.bindingHandlers.submit.init = function (element, valueAccessor) {
    var $form = $(element);

    if ($form.prop('tagName') !== 'FORM') {
        var $button = $form;
        $form = $form.closest('form');

        if ($form.length === 0) {
            throw new Error('Submit binding can be used only in forms');
        }

        $button.on('click', function () {
            $clickedButton = $button;
        });

        var formHandler = function () {
            return function () {
                if ($clickedButton === $button) {
                    return valueAccessor().apply(this, arguments);
                }
                return false;
            };
        };

        overridden.apply(this, [$form[0], formHandler].concat([].splice.call(arguments, 2)));
    } else {
        overridden.apply(this, arguments);
    }
};

视图模型:

var ViewModel = {
    submitA: function () {
        alert('A');
    },
    submitB: function () {
        alert('B');
    }
};

ko.applyBindings(ViewModel);

HTML:

<form method=post>
  <input type=submit data-bind="submit: submitA" value=A>
  <input type=submit data-bind="submit: submitB" value=B>
</form>