이 녹아웃 js 예제는 필드를 편집하고 Tab 키를 누르면 뷰 모델 데이터와 필드 아래의 텍스트가 업데이트되므로 작동합니다.
키를 누를 때마다 뷰 모델 데이터가 업데이트되도록이 코드를 어떻게 변경합니까?
<!doctype html>
<html>
<title>knockout js</title>
<head>
<script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script>
<script type="text/javascript">
window.onload= function() {
var viewModel = {
firstName : ko.observable("Jim"),
lastName : ko.observable("Smith")
};
viewModel.fullName = ko.dependentObservable(function () {
return viewModel.firstName() + " " + viewModel.lastName();
});
ko.applyBindings(viewModel);
}
</script>
</head>
<body>
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
</html>
답변
<body>
<p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
<p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>
로부터 문서
추가 매개 변수
valueUpdate
바인딩에 valueUpdate라는 매개 변수도 포함되어 있으면 변경을 감지하기 위해 KO를 사용해야하는 브라우저 이벤트가 정의됩니다. 다음 문자열 값이 가장 일반적으로 유용한 선택입니다.
“change”(기본값)-사용자가 변경 후 즉시 다른 컨트롤 또는 요소의 경우 포커스를 이동하면 뷰 모델이 업데이트됩니다.
“키업”-사용자가 키를 놓을 때 뷰 모델을 업데이트합니다
“keypress”-사용자가 키를 입력하면 뷰 모델이 업데이트됩니다. 키 업과 달리이 키는 사용자가 키를 누른 상태에서 반복적으로 업데이트됩니다.
- “afterkeydown”-사용자가 문자 입력을 시작하자마자 뷰 모델을 업데이트합니다. 이것은 브라우저의 키 다운 이벤트를 포착하고 이벤트를 비동기 적으로 처리하여 작동합니다.
이러한 옵션 중에서 뷰 모델을 실시간으로 업데이트하려면 “afterkeydown”이 최선의 선택입니다.
답변
버전 3.2 에서는 단순히 텍스트 입력 바인딩을 사용할 수 있습니다 . :
<input data-bind="textInput: userName" />
두 가지 중요한 일을합니다.
- 즉시 업데이트
- 잘라 내기, 끌기, 자동 완성에 대한 브라우저 차이점을 처리합니다 …
따라서 추가 모듈, 사용자 정의 컨트롤 및 기타 사항이 필요하지 않습니다.
답변
afterkeydown
“기본적 으로 ” 업데이트를 valueUpdate
하려면 value
바인딩 핸들러에 바인딩을 삽입하면 됩니다. allBindingsAccessor
처리기가 사용할 새 항목 을 제공하면 됩니다 afterkeydown
.
(function () {
var valueHandler = ko.bindingHandlers.value;
var getInjectValueUpdate = function (allBindingsAccessor) {
var AFTERKEYDOWN = 'afterkeydown';
return function () {
var allBindings = ko.utils.extend({}, allBindingsAccessor()),
valueUpdate = allBindings.valueUpdate;
if (valueUpdate === undefined) {
return ko.utils.extend(allBindings, { valueUpdate: AFTERKEYDOWN });
} else if (typeof valueUpdate === 'string' && valueUpdate !== AFTERKEYDOWN) {
return ko.utils.extend(allBindings, { valueUpdate: [valueUpdate, AFTERKEYDOWN] });
} else if (typeof valueUpdate === 'array' && ko.utils.arrayIndexOf(valueUpdate, AFTERKEYDOWN) === -1) {
valueUpdate = ko.utils.arrayPushAll([AFTERKEYDOWN], valueUpdate);
return ko.utils.extend(allBindings, {valueUpdate: valueUpdate});
}
return allBindings;
};
};
ko.bindingHandlers.value = {
// only needed for init
'init': function (element, valueAccessor, allBindingsAccessor) {
allBindingsAccessor = getInjectValueUpdate(allBindingsAccessor);
return valueHandler.init(element, valueAccessor, allBindingsAccessor);
},
'update': valueHandler.update
};
} ());
value
바인딩을 “재정의”하는 것이 불편한 경우 재정의하는 사용자 정의 바인딩에 다른 이름을 지정하고 해당 바인딩 핸들러를 사용할 수 있습니다.
ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };
이와 같은 솔루션은 Knockout 버전 2.x에 적합합니다. Knockout 팀은 Knockout 버전 3 이상의 textInput 바인딩을 통해 텍스트와 유사한 입력에 대한보다 완벽한 바인딩을 구현 했습니다. 텍스트 입력 및에 대한 모든 텍스트 입력 방법을 처리하도록 설계되었습니다 textarea
. 실시간 업데이트도 처리하여이 접근 방식을 효과적으로 폐기합니다.
답변
Jeff Mercado의 답변은 환상적이지만 불행히도 Knockout 3에서 깨졌습니다.
그러나 Knockout 3 변경을 통해 작업하면서 ko 개발자가 제안한 답변을 찾았습니다. https://github.com/knockout/knockout/pull/932 에서 하단 주석을 참조하십시오 . 그들의 코드 :
//automatically add valueUpdate="afterkeydown" on every value binding
(function () {
var getInjectValueUpdate = function (allBindings) {
return {
has: function (bindingKey) {
return (bindingKey == 'valueUpdate') || allBindings.has(bindingKey);
},
get: function (bindingKey) {
var binding = allBindings.get(bindingKey);
if (bindingKey == 'valueUpdate') {
binding = binding ? [].concat(binding, 'afterkeydown') : 'afterkeydown';
}
return binding;
}
};
};
var valueInitHandler = ko.bindingHandlers.value.init;
ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings, viewModel, bindingContext) {
return valueInitHandler(element, valueAccessor, getInjectValueUpdate(allBindings), viewModel, bindingContext);
};
}());
http://jsfiddle.net/mbest/GKJnt/
Edit
Ko 3.2.0은 이제 새로운 “textInput”바인딩을 통해보다 완벽한 솔루션을 제공합니다. SalvidorDali의 답변보기