knockoutjs передает привязку, не обрабатывая ввод ключа правильно - PullRequest
7 голосов
/ 28 декабря 2011

У меня есть диалоговое окно jquery ui с привязкой отправки knockoutjs на форме. Диалоговое окно может быть закрыто либо нажатием кнопки отмены, либо нажатием кнопки закрытия в строке заголовка диалога, нажатием клавиши «Escape», либо нажатием кнопки «Сохранить». Мое намерение состоит в том, чтобы события отмены, выхода и закрытия строки заголовка закрывали диалог, не применяя к нему никаких действий, в то время как нажатие клавиши ввода или нажатие кнопки «сохранить» должно выполнять действие диалога. Все работает как задумано, кроме клавиши ввода, которая приводит к событию отмены, а не к событию отправки.

Я создал jsfiddle , чтобы проиллюстрировать это, и включите приведенный ниже код для ссылки.

Мои извинения за подробный код ...

Gene

<!-- ko with: dialog -->
<div id="taskdlg" class="resizeableDialog" 
    data-bind="dialog: {autoOpen: false, title: 'Edit task', height: 200, width: 500, modal: true, close: updateCloseState}, openWhen: open">
    <form data-bind="submit: update">
        <table>
            <tr>
                <td style="width: 100px;"><label for="tasktitle">Title</label></td>
                <td width="*">
                    <input id="tasktitle" type="text" placeholder="Task name" data-bind="value: titletext, valueUpdate: 'afterkeydown'" />
                </td>
            </tr>
            <tr>
                <td><button style="float: left;" data-bind="click: cancel">Cancel</button></td>
                <td><button style="float: right;" type="submit">Save</button></td>
            </tr>
        </table>
    </form>
</div>
<!-- /ko -->

<button data-bind="click: editTask">Edit</button>
<span data-bind="text: task"></span>

JavaScript выглядит следующим образом:

ko.bindingHandlers.dialog = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        var options = ko.utils.unwrapObservable(valueAccessor());
        setTimeout(function() { $(element).dialog(options || {}); }, 0);

        //handle disposal (not strictly necessary in this scenario)
         ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
             $(element).dialog("destroy");
         });   
    },
    update: function(element, valueAccessor, allBindingsAccessor) {
         var shouldBeOpen = ko.utils.unwrapObservable(allBindingsAccessor().openWhen);
         $(element)
             .dialog(shouldBeOpen ? "open" : "close");
    }
};

function Task(name) {
    var self = this;
    this.title = ko.observable(name);

    this.toString = function() { return "Task: " + self.title(); };
}

function TaskDialog(viewModel) {
    var self = this;

    this.viewModel = viewModel;
    this.task = ko.observable();
    this.open = ko.observable(false);
    this.titletext = ko.observable();

    this.editTask = function(task) {
        self.task(task);
        self.titletext(task.title());
        self.open(true);
    }

    this.update = function() {
        var task = self.task();
        task.title(self.titletext());
        self.open(false);
    }

    this.updateCloseState = function() {
        if (self.open())
            self.open(false);
    }

    this.cancel = function() {
        self.open(false);
    }
}


function viewModel() {
    var self = this;
    this.dialog = ko.observable(new TaskDialog(self));
    this.task = ko.observable(new Task('sample task'));

    this.editTask = function() {
        self.dialog().editTask(self.task());
    }
};

ko.applyBindings(new viewModel());

1 Ответ

15 голосов
/ 28 декабря 2011

Если кнопка не имеет типа, браузер предполагает, что ее можно считать кнопкой submit.Таким образом, когда вы нажимаете enter, метод кнопки отмены выполняется и предотвращает фактическую отправку по умолчанию.Таким образом, если бы вы переместили кнопку «Сохранить» перед кнопкой «Отмена», она бы работала правильно.

Однако реальный способ исправить это - просто добавить type="button" к вашей отмене:

<button type="button" style="float: left;" data-bind="click: cancel">Cancel</button>

http://jsfiddle.net/rniemeyer/HwbD2/11/

...