2011-12-28 2 views
7

양식에 knockoutjs 제출 바인딩이 포함 된 jquery UI 대화 상자가 있습니다. 취소 버튼을 누르거나, 대화 상자 제목 표시 줄의 닫기 버튼을 누르거나, 이탈을 치거나, 저장 버튼을 눌러 대화 상자를 닫을 수 있습니다. 내 의도는 취소, 탈출 및 제목 표시 줄 닫기 이벤트는 대화 상자에서 Enter 키를 누르거나 '저장'을 클릭하면 대화 상자 작업을 수행해야하는 반면 대화 상자를 닫지 않아야한다는 것입니다. 입력 이벤트가 아니라 취소 이벤트가 발생하는 Enter 키를 제외하고 모두 의도 한대로 작동합니다.knockoutjs 제출 바인딩 처리 안 함 키 입력 올바르게

나는 이것을 설명하기 위해 jsfiddle을 만들었으며, 아래의 코드를 참조하십시오. 자세한 정보 표시 코드

내 사과 ...

유전자

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

자바 스크립트는 다음과 같다 : 버튼 브라우저 다음, 유형이없는

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()); 

답변

15

경우 그것이 submit 버튼으로 간주 될 수 있다고 가정합니다. 따라서 enter을 누르면 취소 버튼의 메소드가 실행되고 실제로 발생하는 기본 제출을 방지합니다. 따라서 취소 버튼을 누르기 전에 저장 버튼을 움직이면 제대로 작동합니다.

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

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

+2

감사 :

그러나, 문제를 해결하는 진정한 방법은 취소에 type="button"를 추가하는 단지입니다! 어리석은 작은 것들로 얼마나 많은 시간을 낭비했는지 놀랍습니다 ... –

+2

예, 저는 이걸 보면서 오랜 시간을 보냈습니다. 마치 우리가 누락되었지만 keyCode 13 등을 캡처하는 데 필요한 모든 코드가 필요하지 않은 것처럼 보였습니다. –